Replace ... with new expansion options
- expand upwards - expand downwards - expand all in both inline and parallel views
This commit is contained in:
parent
cdac9ed86f
commit
fc0ff7cf03
|
@ -0,0 +1,246 @@
|
|||
<script>
|
||||
import createFlash from '~/flash';
|
||||
import { s__ } from '~/locale';
|
||||
import { mapState, mapActions } from 'vuex';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import { UNFOLD_COUNT } from '../constants';
|
||||
import * as utils from '../store/utils';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
const EXPAND_ALL = 0;
|
||||
const EXPAND_UP = 1;
|
||||
const EXPAND_DOWN = 2;
|
||||
|
||||
export default {
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
components: {
|
||||
Icon,
|
||||
},
|
||||
props: {
|
||||
fileHash: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
contextLinesPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
line: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
isTop: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
isBottom: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
colspan: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 3,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
diffViewType: state => state.diffs.diffViewType,
|
||||
diffFiles: state => state.diffs.diffFiles,
|
||||
}),
|
||||
canExpandUp() {
|
||||
return !this.isBottom;
|
||||
},
|
||||
canExpandDown() {
|
||||
return this.isBottom || !this.isTop;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.EXPAND_DOWN = EXPAND_DOWN;
|
||||
this.EXPAND_UP = EXPAND_UP;
|
||||
},
|
||||
methods: {
|
||||
...mapActions('diffs', ['loadMoreLines']),
|
||||
getPrevLineNumber(oldLineNumber, newLineNumber) {
|
||||
const diffFile = utils.findDiffFile(this.diffFiles, this.fileHash);
|
||||
const indexForInline = utils.findIndexInInlineLines(diffFile.highlighted_diff_lines, {
|
||||
oldLineNumber,
|
||||
newLineNumber,
|
||||
});
|
||||
const prevLine = diffFile.highlighted_diff_lines[indexForInline - 2];
|
||||
return (prevLine && prevLine.new_line) || 0;
|
||||
},
|
||||
callLoadMoreLines(
|
||||
endpoint,
|
||||
params,
|
||||
lineNumbers,
|
||||
fileHash,
|
||||
isExpandDown = false,
|
||||
nextLineNumbers = {},
|
||||
) {
|
||||
this.loadMoreLines({ endpoint, params, lineNumbers, fileHash, isExpandDown, nextLineNumbers })
|
||||
.then(() => {
|
||||
this.isRequesting = false;
|
||||
})
|
||||
.catch(() => {
|
||||
createFlash(s__('Diffs|Something went wrong while fetching diff lines.'));
|
||||
this.isRequesting = false;
|
||||
});
|
||||
},
|
||||
handleExpandLines(type = EXPAND_ALL) {
|
||||
if (this.isRequesting) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isRequesting = true;
|
||||
const endpoint = this.contextLinesPath;
|
||||
const { fileHash } = this;
|
||||
const view = this.diffViewType;
|
||||
const oldLineNumber = this.line.meta_data.old_pos || 0;
|
||||
const newLineNumber = this.line.meta_data.new_pos || 0;
|
||||
const offset = newLineNumber - oldLineNumber;
|
||||
|
||||
const expandOptions = { endpoint, fileHash, view, oldLineNumber, newLineNumber, offset };
|
||||
|
||||
if (type === EXPAND_UP) {
|
||||
this.handleExpandUpLines(expandOptions);
|
||||
} else if (type === EXPAND_DOWN) {
|
||||
this.handleExpandDownLines(expandOptions);
|
||||
} else {
|
||||
this.handleExpandAllLines(expandOptions);
|
||||
}
|
||||
},
|
||||
handleExpandUpLines(expandOptions = EXPAND_ALL) {
|
||||
const { endpoint, fileHash, view, oldLineNumber, newLineNumber, offset } = expandOptions;
|
||||
|
||||
const bottom = this.isBottom;
|
||||
const lineNumber = newLineNumber - 1;
|
||||
const to = lineNumber;
|
||||
let since = lineNumber - UNFOLD_COUNT;
|
||||
let unfold = true;
|
||||
|
||||
const prevLineNumber = this.getPrevLineNumber(oldLineNumber, newLineNumber);
|
||||
if (since <= prevLineNumber + 1) {
|
||||
since = prevLineNumber + 1;
|
||||
unfold = false;
|
||||
}
|
||||
|
||||
const params = { since, to, bottom, offset, unfold, view };
|
||||
const lineNumbers = { oldLineNumber, newLineNumber };
|
||||
this.callLoadMoreLines(endpoint, params, lineNumbers, fileHash);
|
||||
},
|
||||
handleExpandDownLines(expandOptions) {
|
||||
const {
|
||||
endpoint,
|
||||
fileHash,
|
||||
view,
|
||||
oldLineNumber: metaOldPos,
|
||||
newLineNumber: metaNewPos,
|
||||
offset,
|
||||
} = expandOptions;
|
||||
|
||||
const bottom = true;
|
||||
const nextLineNumbers = {
|
||||
old_line: metaOldPos,
|
||||
new_line: metaNewPos,
|
||||
};
|
||||
|
||||
let unfold = true;
|
||||
let isExpandDown = false;
|
||||
let oldLineNumber = metaOldPos;
|
||||
let newLineNumber = metaNewPos;
|
||||
let lineNumber = metaNewPos + 1;
|
||||
let since = lineNumber;
|
||||
let to = lineNumber + UNFOLD_COUNT;
|
||||
|
||||
if (!this.isBottom) {
|
||||
const prevLineNumber = this.getPrevLineNumber(oldLineNumber, newLineNumber);
|
||||
|
||||
isExpandDown = true;
|
||||
oldLineNumber = prevLineNumber - offset;
|
||||
newLineNumber = prevLineNumber;
|
||||
lineNumber = prevLineNumber + 1;
|
||||
since = lineNumber;
|
||||
to = lineNumber + UNFOLD_COUNT;
|
||||
|
||||
if (to >= metaNewPos) {
|
||||
to = metaNewPos - 1;
|
||||
unfold = false;
|
||||
}
|
||||
}
|
||||
|
||||
const params = { since, to, bottom, offset, unfold, view };
|
||||
const lineNumbers = { oldLineNumber, newLineNumber };
|
||||
this.callLoadMoreLines(
|
||||
endpoint,
|
||||
params,
|
||||
lineNumbers,
|
||||
fileHash,
|
||||
isExpandDown,
|
||||
nextLineNumbers,
|
||||
);
|
||||
},
|
||||
handleExpandAllLines(expandOptions) {
|
||||
const { endpoint, fileHash, view, oldLineNumber, newLineNumber, offset } = expandOptions;
|
||||
const bottom = this.isBottom;
|
||||
const unfold = false;
|
||||
let since;
|
||||
let to;
|
||||
|
||||
if (this.isTop) {
|
||||
since = 1;
|
||||
to = newLineNumber - 1;
|
||||
} else if (bottom) {
|
||||
since = newLineNumber + 1;
|
||||
to = -1;
|
||||
} else {
|
||||
const prevLineNumber = this.getPrevLineNumber(oldLineNumber, newLineNumber);
|
||||
since = prevLineNumber + 1;
|
||||
to = newLineNumber - 1;
|
||||
}
|
||||
|
||||
const params = { since, to, bottom, offset, unfold, view };
|
||||
const lineNumbers = { oldLineNumber, newLineNumber };
|
||||
this.callLoadMoreLines(endpoint, params, lineNumbers, fileHash);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<td :colspan="colspan">
|
||||
<div class="content">
|
||||
<a
|
||||
v-if="canExpandUp"
|
||||
v-tooltip
|
||||
class="cursor-pointer js-unfold unfold-icon"
|
||||
data-placement="top"
|
||||
data-container="body"
|
||||
:title="__('Expand up')"
|
||||
@click="handleExpandLines(EXPAND_UP)"
|
||||
>
|
||||
<!-- TODO: remove style & replace with correct icon, waiting for MR https://gitlab.com/gitlab-org/gitlab-design/issues/499 -->
|
||||
<icon :size="12" name="expand-left" aria-hidden="true" style="transform: rotate(270deg);" />
|
||||
</a>
|
||||
<a class="mx-2 cursor-pointer js-unfold-all" @click="handleExpandLines()">
|
||||
<span>{{ s__('Diffs|Show all lines') }}</span>
|
||||
</a>
|
||||
<a
|
||||
v-if="canExpandDown"
|
||||
v-tooltip
|
||||
class="cursor-pointer js-unfold-down has-tooltip unfold-icon"
|
||||
data-placement="top"
|
||||
data-container="body"
|
||||
:title="__('Expand down')"
|
||||
@click="handleExpandLines(EXPAND_DOWN)"
|
||||
>
|
||||
<!-- TODO: remove style & replace with correct icon, waiting for MR https://gitlab.com/gitlab-org/gitlab-design/issues/499 -->
|
||||
<icon :size="12" name="expand-left" aria-hidden="true" style="transform: rotate(90deg);" />
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</template>
|
|
@ -1,11 +1,8 @@
|
|||
<script>
|
||||
import createFlash from '~/flash';
|
||||
import { s__ } from '~/locale';
|
||||
import { mapState, mapGetters, mapActions } from 'vuex';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import DiffGutterAvatars from './diff_gutter_avatars.vue';
|
||||
import { LINE_POSITION_RIGHT, UNFOLD_COUNT } from '../constants';
|
||||
import * as utils from '../store/utils';
|
||||
import { LINE_POSITION_RIGHT } from '../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -115,89 +112,36 @@ export default {
|
|||
handleCommentButton() {
|
||||
this.showCommentForm({ lineCode: this.line.line_code, fileHash: this.fileHash });
|
||||
},
|
||||
handleLoadMoreLines() {
|
||||
if (this.isRequesting) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isRequesting = true;
|
||||
const endpoint = this.contextLinesPath;
|
||||
const oldLineNumber = this.line.meta_data.old_pos || 0;
|
||||
const newLineNumber = this.line.meta_data.new_pos || 0;
|
||||
const offset = newLineNumber - oldLineNumber;
|
||||
const bottom = this.isBottom;
|
||||
const { fileHash } = this;
|
||||
const view = this.diffViewType;
|
||||
let unfold = true;
|
||||
let lineNumber = newLineNumber - 1;
|
||||
let since = lineNumber - UNFOLD_COUNT;
|
||||
let to = lineNumber;
|
||||
|
||||
if (bottom) {
|
||||
lineNumber = newLineNumber + 1;
|
||||
since = lineNumber;
|
||||
to = lineNumber + UNFOLD_COUNT;
|
||||
} else {
|
||||
const diffFile = utils.findDiffFile(this.diffFiles, this.fileHash);
|
||||
const indexForInline = utils.findIndexInInlineLines(diffFile.highlighted_diff_lines, {
|
||||
oldLineNumber,
|
||||
newLineNumber,
|
||||
});
|
||||
const prevLine = diffFile.highlighted_diff_lines[indexForInline - 2];
|
||||
const prevLineNumber = (prevLine && prevLine.new_line) || 0;
|
||||
|
||||
if (since <= prevLineNumber + 1) {
|
||||
since = prevLineNumber + 1;
|
||||
unfold = false;
|
||||
}
|
||||
}
|
||||
|
||||
const params = { since, to, bottom, offset, unfold, view };
|
||||
const lineNumbers = { oldLineNumber, newLineNumber };
|
||||
this.loadMoreLines({ endpoint, params, lineNumbers, fileHash })
|
||||
.then(() => {
|
||||
this.isRequesting = false;
|
||||
})
|
||||
.catch(() => {
|
||||
createFlash(s__('Diffs|Something went wrong while fetching diff lines.'));
|
||||
this.isRequesting = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<span v-if="isMatchLine" class="context-cell" role="button" @click="handleLoadMoreLines"
|
||||
>...</span
|
||||
<button
|
||||
v-if="shouldRenderCommentButton"
|
||||
v-show="shouldShowCommentButton"
|
||||
type="button"
|
||||
class="add-diff-note js-add-diff-note-button qa-diff-comment"
|
||||
title="Add a comment to this line"
|
||||
@click="handleCommentButton"
|
||||
>
|
||||
<template v-else>
|
||||
<button
|
||||
v-if="shouldRenderCommentButton"
|
||||
v-show="shouldShowCommentButton"
|
||||
type="button"
|
||||
class="add-diff-note js-add-diff-note-button qa-diff-comment"
|
||||
title="Add a comment to this line"
|
||||
@click="handleCommentButton"
|
||||
>
|
||||
<icon :size="12" name="comment" />
|
||||
</button>
|
||||
<a
|
||||
v-if="lineNumber"
|
||||
:data-linenumber="lineNumber"
|
||||
:href="lineHref"
|
||||
@click="setHighlightedRow(lineCode)"
|
||||
>
|
||||
</a>
|
||||
<diff-gutter-avatars
|
||||
v-if="shouldShowAvatarsOnGutter"
|
||||
:discussions="line.discussions"
|
||||
:discussions-expanded="line.discussionsExpanded"
|
||||
@toggleLineDiscussions="
|
||||
toggleLineDiscussions({ lineCode, fileHash, expanded: !line.discussionsExpanded })
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
<icon :size="12" name="comment" />
|
||||
</button>
|
||||
<a
|
||||
v-if="lineNumber"
|
||||
:data-linenumber="lineNumber"
|
||||
:href="lineHref"
|
||||
@click="setHighlightedRow(lineCode)"
|
||||
>
|
||||
</a>
|
||||
<diff-gutter-avatars
|
||||
v-if="shouldShowAvatarsOnGutter"
|
||||
:discussions="line.discussions"
|
||||
:discussions-expanded="line.discussionsExpanded"
|
||||
@toggleLineDiscussions="
|
||||
toggleLineDiscussions({ lineCode, fileHash, expanded: !line.discussionsExpanded })
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<script>
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import DiffExpansionCell from './diff_expansion_cell.vue';
|
||||
import { MATCH_LINE_TYPE } from '../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
DiffExpansionCell,
|
||||
},
|
||||
props: {
|
||||
fileHash: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
contextLinesPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
line: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
isTop: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
isBottom: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isMatchLine() {
|
||||
return this.line.type === MATCH_LINE_TYPE;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tr v-if="isMatchLine" class="line_expansion match">
|
||||
<diff-expansion-cell
|
||||
:file-hash="fileHash"
|
||||
:context-lines-path="contextLinesPath"
|
||||
:line="line"
|
||||
:is-top="isTop"
|
||||
:is-bottom="isBottom"
|
||||
/>
|
||||
</tr>
|
||||
</template>
|
|
@ -2,6 +2,7 @@
|
|||
import { mapActions, mapState } from 'vuex';
|
||||
import DiffTableCell from './diff_table_cell.vue';
|
||||
import {
|
||||
MATCH_LINE_TYPE,
|
||||
NEW_LINE_TYPE,
|
||||
OLD_LINE_TYPE,
|
||||
CONTEXT_LINE_TYPE,
|
||||
|
@ -58,6 +59,9 @@ export default {
|
|||
inlineRowId() {
|
||||
return this.line.line_code || `${this.fileHash}_${this.line.old_line}_${this.line.new_line}`;
|
||||
},
|
||||
isMatchLine() {
|
||||
return this.line.type === MATCH_LINE_TYPE;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.newLineType = NEW_LINE_TYPE;
|
||||
|
@ -81,6 +85,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<tr
|
||||
v-if="!isMatchLine"
|
||||
:id="inlineRowId"
|
||||
:class="classNameMap"
|
||||
class="line_holder"
|
||||
|
|
|
@ -3,6 +3,7 @@ import { mapGetters } from 'vuex';
|
|||
import draftCommentsMixin from 'ee_else_ce/diffs/mixins/draft_comments';
|
||||
import inlineDiffTableRow from './inline_diff_table_row.vue';
|
||||
import inlineDiffCommentRow from './inline_diff_comment_row.vue';
|
||||
import inlineDiffExpansionRow from './inline_diff_expansion_row.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -10,6 +11,7 @@ export default {
|
|||
inlineDiffTableRow,
|
||||
InlineDraftCommentRow: () =>
|
||||
import('ee_component/batch_comments/components/inline_draft_comment_row.vue'),
|
||||
inlineDiffExpansionRow,
|
||||
},
|
||||
mixins: [draftCommentsMixin],
|
||||
props: {
|
||||
|
@ -43,10 +45,24 @@ export default {
|
|||
:data-commit-id="commitId"
|
||||
class="code diff-wrap-lines js-syntax-highlight text-file js-diff-inline-view"
|
||||
>
|
||||
<!-- Need to insert an empty row to solve "table-layout:fixed" equal width when expansion row is the first line -->
|
||||
<tr>
|
||||
<td style="width: 50px;"></td>
|
||||
<td style="width: 50px;"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tbody>
|
||||
<template v-for="(line, index) in diffLines">
|
||||
<inline-diff-expansion-row
|
||||
:key="`expand-${index}`"
|
||||
:file-hash="diffFile.file_hash"
|
||||
:context-lines-path="diffFile.context_lines_path"
|
||||
:line="line"
|
||||
:is-top="index === 0"
|
||||
:is-bottom="index + 1 === diffLinesLength"
|
||||
/>
|
||||
<inline-diff-table-row
|
||||
:key="line.line_code"
|
||||
:key="`${line.line_code || index}`"
|
||||
:file-hash="diffFile.file_hash"
|
||||
:context-lines-path="diffFile.context_lines_path"
|
||||
:line="line"
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<script>
|
||||
import { MATCH_LINE_TYPE } from '../constants';
|
||||
import DiffExpansionCell from './diff_expansion_cell.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DiffExpansionCell,
|
||||
},
|
||||
props: {
|
||||
fileHash: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
contextLinesPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
line: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
isTop: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
isBottom: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isMatchLineLeft() {
|
||||
return this.line.left && this.line.left.type === MATCH_LINE_TYPE;
|
||||
},
|
||||
isMatchLineRight() {
|
||||
return this.line.right && this.line.right.type === MATCH_LINE_TYPE;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<tr class="line_expansion match">
|
||||
<template v-if="isMatchLineLeft || isMatchLineRight">
|
||||
<diff-expansion-cell
|
||||
:file-hash="fileHash"
|
||||
:context-lines-path="contextLinesPath"
|
||||
:line="line.left"
|
||||
:is-top="isTop"
|
||||
:is-bottom="isBottom"
|
||||
:colspan="4"
|
||||
/>
|
||||
</template>
|
||||
</tr>
|
||||
</template>
|
|
@ -3,6 +3,7 @@ import { mapActions, mapState } from 'vuex';
|
|||
import $ from 'jquery';
|
||||
import DiffTableCell from './diff_table_cell.vue';
|
||||
import {
|
||||
MATCH_LINE_TYPE,
|
||||
NEW_LINE_TYPE,
|
||||
OLD_LINE_TYPE,
|
||||
CONTEXT_LINE_TYPE,
|
||||
|
@ -75,6 +76,12 @@ export default {
|
|||
},
|
||||
];
|
||||
},
|
||||
isMatchLineLeft() {
|
||||
return this.line.left && this.line.left.type === MATCH_LINE_TYPE;
|
||||
},
|
||||
isMatchLineRight() {
|
||||
return this.line.right && this.line.right.type === MATCH_LINE_TYPE;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.newLineType = NEW_LINE_TYPE;
|
||||
|
@ -122,7 +129,7 @@ export default {
|
|||
@mouseover="handleMouseMove"
|
||||
@mouseout="handleMouseMove"
|
||||
>
|
||||
<template v-if="line.left">
|
||||
<template v-if="line.left && !isMatchLineLeft">
|
||||
<diff-table-cell
|
||||
:file-hash="fileHash"
|
||||
:context-lines-path="contextLinesPath"
|
||||
|
@ -148,7 +155,7 @@ export default {
|
|||
<td class="diff-line-num old_line empty-cell"></td>
|
||||
<td class="line_content parallel left-side empty-cell"></td>
|
||||
</template>
|
||||
<template v-if="line.right">
|
||||
<template v-if="line.right && !isMatchLineRight">
|
||||
<diff-table-cell
|
||||
:file-hash="fileHash"
|
||||
:context-lines-path="contextLinesPath"
|
||||
|
|
|
@ -3,9 +3,11 @@ import { mapGetters } from 'vuex';
|
|||
import draftCommentsMixin from 'ee_else_ce/diffs/mixins/draft_comments';
|
||||
import parallelDiffTableRow from './parallel_diff_table_row.vue';
|
||||
import parallelDiffCommentRow from './parallel_diff_comment_row.vue';
|
||||
import parallelDiffExpansionRow from './parallel_diff_expansion_row.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
parallelDiffExpansionRow,
|
||||
parallelDiffTableRow,
|
||||
parallelDiffCommentRow,
|
||||
ParallelDraftCommentRow: () =>
|
||||
|
@ -43,8 +45,23 @@ export default {
|
|||
:data-commit-id="commitId"
|
||||
class="code diff-wrap-lines js-syntax-highlight text-file"
|
||||
>
|
||||
<!-- Need to insert an empty row to solve "table-layout:fixed" equal width when expansion row is the first line -->
|
||||
<tr>
|
||||
<td style="width: 50px;"></td>
|
||||
<td></td>
|
||||
<td style="width: 50px;"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tbody>
|
||||
<template v-for="(line, index) in diffLines">
|
||||
<parallel-diff-expansion-row
|
||||
:key="`expand-${index}`"
|
||||
:file-hash="diffFile.file_hash"
|
||||
:context-lines-path="diffFile.context_lines_path"
|
||||
:line="line"
|
||||
:is-top="index === 0"
|
||||
:is-bottom="index + 1 === diffLinesLength"
|
||||
/>
|
||||
<parallel-diff-table-row
|
||||
:key="line.line_code"
|
||||
:file-hash="diffFile.file_hash"
|
||||
|
|
|
@ -183,7 +183,7 @@ export const cancelCommentForm = ({ commit }, { lineCode, fileHash }) => {
|
|||
};
|
||||
|
||||
export const loadMoreLines = ({ commit }, options) => {
|
||||
const { endpoint, params, lineNumbers, fileHash } = options;
|
||||
const { endpoint, params, lineNumbers, fileHash, isExpandDown, nextLineNumbers } = options;
|
||||
|
||||
params.from_merge_request = true;
|
||||
|
||||
|
@ -195,6 +195,8 @@ export const loadMoreLines = ({ commit }, options) => {
|
|||
contextLines,
|
||||
params,
|
||||
fileHash,
|
||||
isExpandDown,
|
||||
nextLineNumbers,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -71,18 +71,30 @@ export default {
|
|||
},
|
||||
|
||||
[types.ADD_CONTEXT_LINES](state, options) {
|
||||
const { lineNumbers, contextLines, fileHash } = options;
|
||||
const { lineNumbers, contextLines, fileHash, isExpandDown, nextLineNumbers } = options;
|
||||
const { bottom } = options.params;
|
||||
const diffFile = findDiffFile(state.diffFiles, fileHash);
|
||||
|
||||
removeMatchLine(diffFile, lineNumbers, bottom);
|
||||
|
||||
const lines = addLineReferences(contextLines, lineNumbers, bottom).map(line => ({
|
||||
...line,
|
||||
line_code: line.line_code || `${fileHash}_${line.old_line}_${line.new_line}`,
|
||||
discussions: line.discussions || [],
|
||||
hasForm: false,
|
||||
}));
|
||||
const lines = addLineReferences(
|
||||
contextLines,
|
||||
lineNumbers,
|
||||
bottom,
|
||||
isExpandDown,
|
||||
nextLineNumbers,
|
||||
).map(line => {
|
||||
const lineCode =
|
||||
line.type === 'match'
|
||||
? `${fileHash}_${line.meta_data.old_pos}_${line.meta_data.new_pos}_match`
|
||||
: line.line_code || `${fileHash}_${line.old_line}_${line.new_line}`;
|
||||
return {
|
||||
...line,
|
||||
line_code: lineCode,
|
||||
discussions: line.discussions || [],
|
||||
hasForm: false,
|
||||
};
|
||||
});
|
||||
|
||||
addContextLines({
|
||||
inlineLines: diffFile.highlighted_diff_lines,
|
||||
|
@ -90,6 +102,7 @@ export default {
|
|||
contextLines: lines,
|
||||
bottom,
|
||||
lineNumbers,
|
||||
isExpandDown,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ export function removeMatchLine(diffFile, lineNumbers, bottom) {
|
|||
diffFile.parallel_diff_lines.splice(indexForParallel + factor, 1);
|
||||
}
|
||||
|
||||
export function addLineReferences(lines, lineNumbers, bottom) {
|
||||
export function addLineReferences(lines, lineNumbers, bottom, isExpandDown, nextLineNumbers) {
|
||||
const { oldLineNumber, newLineNumber } = lineNumbers;
|
||||
const lineCount = lines.length;
|
||||
let matchLineIndex = -1;
|
||||
|
@ -135,15 +135,20 @@ export function addLineReferences(lines, lineNumbers, bottom) {
|
|||
new_line: bottom ? newLineNumber + index + 1 : newLineNumber + index - lineCount,
|
||||
});
|
||||
}
|
||||
|
||||
return l;
|
||||
});
|
||||
|
||||
if (matchLineIndex > -1) {
|
||||
const line = linesWithNumbers[matchLineIndex];
|
||||
const targetLine = bottom
|
||||
? linesWithNumbers[matchLineIndex - 1]
|
||||
: linesWithNumbers[matchLineIndex + 1];
|
||||
let targetLine;
|
||||
|
||||
if (isExpandDown) {
|
||||
targetLine = nextLineNumbers;
|
||||
} else if (bottom) {
|
||||
targetLine = linesWithNumbers[matchLineIndex - 1];
|
||||
} else {
|
||||
targetLine = linesWithNumbers[matchLineIndex + 1];
|
||||
}
|
||||
|
||||
Object.assign(line, {
|
||||
meta_data: {
|
||||
|
@ -152,26 +157,27 @@ export function addLineReferences(lines, lineNumbers, bottom) {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
return linesWithNumbers;
|
||||
}
|
||||
|
||||
export function addContextLines(options) {
|
||||
const { inlineLines, parallelLines, contextLines, lineNumbers } = options;
|
||||
const { inlineLines, parallelLines, contextLines, lineNumbers, isExpandDown } = options;
|
||||
const normalizedParallelLines = contextLines.map(line => ({
|
||||
left: line,
|
||||
right: line,
|
||||
line_code: line.line_code,
|
||||
}));
|
||||
const factor = isExpandDown ? 1 : 0;
|
||||
|
||||
if (options.bottom) {
|
||||
if (!isExpandDown && options.bottom) {
|
||||
inlineLines.push(...contextLines);
|
||||
parallelLines.push(...normalizedParallelLines);
|
||||
} else {
|
||||
const inlineIndex = findIndexInInlineLines(inlineLines, lineNumbers);
|
||||
const parallelIndex = findIndexInParallelLines(parallelLines, lineNumbers);
|
||||
inlineLines.splice(inlineIndex, 0, ...contextLines);
|
||||
parallelLines.splice(parallelIndex, 0, ...normalizedParallelLines);
|
||||
|
||||
inlineLines.splice(inlineIndex + factor, 0, ...contextLines);
|
||||
parallelLines.splice(parallelIndex + factor, 0, ...normalizedParallelLines);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,26 @@ pre.code,
|
|||
color: $white-code-color;
|
||||
}
|
||||
|
||||
// Expansion line
|
||||
.line_expansion {
|
||||
background-color: $gray-light;
|
||||
|
||||
td {
|
||||
border-top: 1px solid $border-color;
|
||||
border-bottom: 1px solid $border-color;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $blue-600;
|
||||
}
|
||||
|
||||
.unfold-icon {
|
||||
display: inline-block;
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Diff line
|
||||
.line_holder {
|
||||
&.match .line_content,
|
||||
|
|
|
@ -408,6 +408,14 @@ table.code {
|
|||
table-layout: fixed;
|
||||
border-radius: 0 0 $border-radius-default $border-radius-default;
|
||||
|
||||
tr:first-of-type.line_expansion > td {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
tr:nth-last-of-type(2).line_expansion > td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
tr.line_holder td {
|
||||
line-height: $code-line-height;
|
||||
font-size: $code-font-size;
|
||||
|
|
|
@ -9,7 +9,7 @@ module Blobs
|
|||
|
||||
attribute :full, Boolean, default: false
|
||||
attribute :since, GtOneCoercion
|
||||
attribute :to, GtOneCoercion
|
||||
attribute :to, Integer
|
||||
attribute :bottom, Boolean
|
||||
attribute :unfold, Boolean, default: true
|
||||
attribute :offset, Integer
|
||||
|
@ -24,9 +24,7 @@ module Blobs
|
|||
@all_lines = blob.data.lines
|
||||
super(params)
|
||||
|
||||
if full?
|
||||
self.attributes = { since: 1, to: @all_lines.size, bottom: false, unfold: false, offset: 0, indent: 0 }
|
||||
end
|
||||
self.attributes = prepare_attributes
|
||||
end
|
||||
|
||||
# Returns an array of Gitlab::Diff::Line with match line added
|
||||
|
@ -43,7 +41,9 @@ module Blobs
|
|||
end
|
||||
|
||||
def lines
|
||||
@lines ||= limit(highlight.lines).map(&:html_safe)
|
||||
strong_memoize(:lines) do
|
||||
limit(highlight.lines).map(&:html_safe)
|
||||
end
|
||||
end
|
||||
|
||||
def match_line_text
|
||||
|
@ -56,10 +56,34 @@ module Blobs
|
|||
|
||||
private
|
||||
|
||||
def prepare_attributes
|
||||
return attributes unless full? || to == -1
|
||||
|
||||
full_opts = {
|
||||
since: 1,
|
||||
to: all_lines_size,
|
||||
bottom: false,
|
||||
unfold: false,
|
||||
offset: 0,
|
||||
indent: 0
|
||||
}
|
||||
|
||||
return full_opts if full?
|
||||
|
||||
full_opts.merge(attributes.slice(:since))
|
||||
end
|
||||
|
||||
def all_lines_size
|
||||
strong_memoize(:all_lines_size) do
|
||||
@all_lines.size
|
||||
end
|
||||
end
|
||||
|
||||
def add_match_line(diff_lines)
|
||||
return unless unfold?
|
||||
return if bottom? && to >= all_lines_size
|
||||
|
||||
if bottom? && to < @all_lines.size
|
||||
if bottom? && to < all_lines_size
|
||||
old_pos = to - offset
|
||||
new_pos = to
|
||||
elsif since != 1
|
||||
|
@ -75,7 +99,9 @@ module Blobs
|
|||
end
|
||||
|
||||
def limited_blob_lines
|
||||
@limited_blob_lines ||= limit(@all_lines)
|
||||
strong_memoize(:limited_blob_lines) do
|
||||
limit(@all_lines)
|
||||
end
|
||||
end
|
||||
|
||||
def limit(lines)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add new expansion options for merge request diffs
|
||||
merge_request: 30927
|
||||
author:
|
||||
type: added
|
|
@ -3899,6 +3899,9 @@ msgstr ""
|
|||
msgid "Diffs|No file name available"
|
||||
msgstr ""
|
||||
|
||||
msgid "Diffs|Show all lines"
|
||||
msgstr ""
|
||||
|
||||
msgid "Diffs|Something went wrong while fetching diff lines."
|
||||
msgstr ""
|
||||
|
||||
|
@ -4649,12 +4652,18 @@ msgstr ""
|
|||
msgid "Expand all"
|
||||
msgstr ""
|
||||
|
||||
msgid "Expand down"
|
||||
msgstr ""
|
||||
|
||||
msgid "Expand dropdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Expand sidebar"
|
||||
msgstr ""
|
||||
|
||||
msgid "Expand up"
|
||||
msgstr ""
|
||||
|
||||
msgid "Expiration date"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -68,12 +68,12 @@ describe 'Merge request > User posts diff notes', :js do
|
|||
context 'with a match line' do
|
||||
it 'does not allow commenting on the left side' do
|
||||
line_holder = find('.match', match: :first).find(:xpath, '..')
|
||||
should_not_allow_commenting(line_holder, 'left')
|
||||
match_should_not_allow_commenting(line_holder)
|
||||
end
|
||||
|
||||
it 'does not allow commenting on the right side' do
|
||||
line_holder = find('.match', match: :first).find(:xpath, '..')
|
||||
should_not_allow_commenting(line_holder, 'right')
|
||||
match_should_not_allow_commenting(line_holder)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -136,7 +136,7 @@ describe 'Merge request > User posts diff notes', :js do
|
|||
|
||||
context 'with a match line' do
|
||||
it 'does not allow commenting' do
|
||||
should_not_allow_commenting(find('.match', match: :first))
|
||||
match_should_not_allow_commenting(find('.match', match: :first))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -222,7 +222,7 @@ describe 'Merge request > User posts diff notes', :js do
|
|||
|
||||
context 'with a match line' do
|
||||
it 'does not allow commenting' do
|
||||
should_not_allow_commenting(find('.match', match: :first))
|
||||
match_should_not_allow_commenting(find('.match', match: :first))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -251,6 +251,10 @@ describe 'Merge request > User posts diff notes', :js do
|
|||
expect(line[:num]).not_to have_css comment_button_class
|
||||
end
|
||||
|
||||
def match_should_not_allow_commenting(line_holder)
|
||||
expect(line_holder).not_to have_css comment_button_class
|
||||
end
|
||||
|
||||
def write_comment_on_line(line_holder, diff_side)
|
||||
click_diff_line(line_holder, diff_side)
|
||||
|
||||
|
|
|
@ -17,11 +17,25 @@ describe 'User views diffs', :js do
|
|||
end
|
||||
|
||||
shared_examples 'unfold diffs' do
|
||||
it 'unfolds diffs' do
|
||||
it 'unfolds diffs upwards' do
|
||||
first('.js-unfold').click
|
||||
|
||||
expect(find('.file-holder[id="a5cc2925ca8258af241be7e5b0381edf30266302"] .text-file')).to have_content('.bundle')
|
||||
end
|
||||
|
||||
it 'unfolds diffs to the start' do
|
||||
first('.js-unfold-all').click
|
||||
expect(find('.file-holder[id="a5cc2925ca8258af241be7e5b0381edf30266302"] .text-file')).to have_content('.rbc')
|
||||
end
|
||||
|
||||
it 'unfolds diffs downwards' do
|
||||
first('.js-unfold-down').click
|
||||
expect(find('.file-holder[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd"] .text-file')).to have_content('.popen3')
|
||||
end
|
||||
|
||||
it 'unfolds diffs to the end' do
|
||||
page.all('.js-unfold-down').last
|
||||
expect(find('.file-holder[id="6eb14e00385d2fb284765eb1cd8d420d33d63fc9"] .text-file')).to have_content('end')
|
||||
end
|
||||
end
|
||||
|
||||
it 'shows diffs' do
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/mr_notes/stores';
|
||||
import DiffExpansionCell from '~/diffs/components/diff_expansion_cell.vue';
|
||||
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
|
||||
const EXPAND_UP_CLASS = '.js-unfold';
|
||||
const EXPAND_DOWN_CLASS = '.js-unfold-down';
|
||||
const EXPAND_ALL_CLASS = '.js-unfold-all';
|
||||
|
||||
describe('DiffExpansionCell', () => {
|
||||
const matchLine = diffFileMockData.highlighted_diff_lines[5];
|
||||
|
||||
const createComponent = (options = {}) => {
|
||||
const cmp = Vue.extend(DiffExpansionCell);
|
||||
const defaults = {
|
||||
fileHash: diffFileMockData.file_hash,
|
||||
contextLinesPath: 'contextLinesPath',
|
||||
line: matchLine,
|
||||
isTop: false,
|
||||
isBottom: false,
|
||||
};
|
||||
const props = Object.assign({}, defaults, options);
|
||||
|
||||
return createComponentWithStore(cmp, store, props).$mount();
|
||||
};
|
||||
|
||||
describe('top row', () => {
|
||||
it('should have "expand up" and "show all" option', () => {
|
||||
const vm = createComponent({
|
||||
isTop: true,
|
||||
});
|
||||
const el = vm.$el;
|
||||
|
||||
expect(el.querySelector(EXPAND_UP_CLASS)).not.toBe(null);
|
||||
expect(el.querySelector(EXPAND_DOWN_CLASS)).toBe(null);
|
||||
expect(el.querySelector(EXPAND_ALL_CLASS)).not.toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('middle row', () => {
|
||||
it('should have "expand down", "show all", "expand up" option', () => {
|
||||
const vm = createComponent();
|
||||
const el = vm.$el;
|
||||
|
||||
expect(el.querySelector(EXPAND_UP_CLASS)).not.toBe(null);
|
||||
expect(el.querySelector(EXPAND_DOWN_CLASS)).not.toBe(null);
|
||||
expect(el.querySelector(EXPAND_ALL_CLASS)).not.toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bottom row', () => {
|
||||
it('should have "expand down" and "show all" option', () => {
|
||||
const vm = createComponent({
|
||||
isBottom: true,
|
||||
});
|
||||
const el = vm.$el;
|
||||
|
||||
expect(el.querySelector(EXPAND_UP_CLASS)).toBe(null);
|
||||
expect(el.querySelector(EXPAND_DOWN_CLASS)).not.toBe(null);
|
||||
expect(el.querySelector(EXPAND_ALL_CLASS)).not.toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -70,15 +70,6 @@ describe('DiffLineGutterContent', () => {
|
|||
});
|
||||
|
||||
describe('template', () => {
|
||||
it('should render three dots for context lines', () => {
|
||||
const component = createComponent({
|
||||
isMatchLine: true,
|
||||
});
|
||||
|
||||
expect(component.$el.querySelector('span').classList.contains('context-cell')).toEqual(true);
|
||||
expect(component.$el.innerText).toEqual('...');
|
||||
});
|
||||
|
||||
it('should render comment button', () => {
|
||||
const component = createComponent({
|
||||
showCommentButton: true,
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/mr_notes/stores';
|
||||
import InlineDiffExpansionRow from '~/diffs/components/inline_diff_expansion_row.vue';
|
||||
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
|
||||
describe('InlineDiffExpansionRow', () => {
|
||||
const matchLine = diffFileMockData.highlighted_diff_lines[5];
|
||||
|
||||
const createComponent = (options = {}) => {
|
||||
const cmp = Vue.extend(InlineDiffExpansionRow);
|
||||
const defaults = {
|
||||
fileHash: diffFileMockData.file_hash,
|
||||
contextLinesPath: 'contextLinesPath',
|
||||
line: matchLine,
|
||||
isTop: false,
|
||||
isBottom: false,
|
||||
};
|
||||
const props = Object.assign({}, defaults, options);
|
||||
|
||||
return createComponentWithStore(cmp, store, props).$mount();
|
||||
};
|
||||
|
||||
describe('template', () => {
|
||||
it('should render expansion row for match lines', () => {
|
||||
const vm = createComponent();
|
||||
|
||||
expect(vm.$el.classList.contains('line_expansion')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -28,9 +28,9 @@ describe('InlineDiffView', () => {
|
|||
it('should have rendered diff lines', () => {
|
||||
const el = component.$el;
|
||||
|
||||
expect(el.querySelectorAll('tr.line_holder').length).toEqual(6);
|
||||
expect(el.querySelectorAll('tr.line_holder').length).toEqual(5);
|
||||
expect(el.querySelectorAll('tr.line_holder.new').length).toEqual(2);
|
||||
expect(el.querySelectorAll('tr.line_holder.match').length).toEqual(1);
|
||||
expect(el.querySelectorAll('tr.line_expansion.match').length).toEqual(1);
|
||||
expect(el.textContent.indexOf('Bad dates')).toBeGreaterThan(-1);
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/mr_notes/stores';
|
||||
import ParallelDiffExpansionRow from '~/diffs/components/parallel_diff_expansion_row.vue';
|
||||
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
|
||||
describe('ParallelDiffExpansionRow', () => {
|
||||
const matchLine = diffFileMockData.highlighted_diff_lines[5];
|
||||
|
||||
const createComponent = (options = {}) => {
|
||||
const cmp = Vue.extend(ParallelDiffExpansionRow);
|
||||
const defaults = {
|
||||
fileHash: diffFileMockData.file_hash,
|
||||
contextLinesPath: 'contextLinesPath',
|
||||
line: matchLine,
|
||||
isTop: false,
|
||||
isBottom: false,
|
||||
};
|
||||
const props = Object.assign({}, defaults, options);
|
||||
|
||||
return createComponentWithStore(cmp, store, props).$mount();
|
||||
};
|
||||
|
||||
describe('template', () => {
|
||||
it('should render expansion row for match lines', () => {
|
||||
const vm = createComponent();
|
||||
|
||||
expect(vm.$el.classList.contains('line_expansion')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -380,7 +380,9 @@ describe('DiffsStoreActions', () => {
|
|||
const params = { since: 6, to: 26 };
|
||||
const lineNumbers = { oldLineNumber: 3, newLineNumber: 5 };
|
||||
const fileHash = 'ff9200';
|
||||
const options = { endpoint, params, lineNumbers, fileHash };
|
||||
const isExpandDown = false;
|
||||
const nextLineNumbers = {};
|
||||
const options = { endpoint, params, lineNumbers, fileHash, isExpandDown, nextLineNumbers };
|
||||
const mock = new MockAdapter(axios);
|
||||
const contextLines = { contextLines: [{ lineCode: 6 }] };
|
||||
mock.onGet(endpoint).reply(200, contextLines);
|
||||
|
@ -392,7 +394,7 @@ describe('DiffsStoreActions', () => {
|
|||
[
|
||||
{
|
||||
type: types.ADD_CONTEXT_LINES,
|
||||
payload: { lineNumbers, contextLines, params, fileHash },
|
||||
payload: { lineNumbers, contextLines, params, fileHash, isExpandDown, nextLineNumbers },
|
||||
},
|
||||
],
|
||||
[],
|
||||
|
|
|
@ -81,6 +81,8 @@ describe('DiffsStoreMutations', () => {
|
|||
params: {
|
||||
bottom: true,
|
||||
},
|
||||
isExpandDown: false,
|
||||
nextLineNumbers: {},
|
||||
};
|
||||
const diffFile = {
|
||||
file_hash: options.fileHash,
|
||||
|
@ -108,6 +110,8 @@ describe('DiffsStoreMutations', () => {
|
|||
options.contextLines,
|
||||
options.lineNumbers,
|
||||
options.params.bottom,
|
||||
options.isExpandDown,
|
||||
options.nextLineNumbers,
|
||||
);
|
||||
|
||||
expect(addContextLinesSpy).toHaveBeenCalledWith({
|
||||
|
@ -116,6 +120,7 @@ describe('DiffsStoreMutations', () => {
|
|||
contextLines: options.contextLines,
|
||||
bottom: options.params.bottom,
|
||||
lineNumbers: options.lineNumbers,
|
||||
isExpandDown: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -260,6 +260,17 @@ describe('DiffsStoreUtils', () => {
|
|||
expect(linesWithReferences[1].meta_data.old_pos).toEqual(2);
|
||||
expect(linesWithReferences[1].meta_data.new_pos).toEqual(3);
|
||||
});
|
||||
|
||||
it('should add correct line references when isExpandDown is true', () => {
|
||||
const lines = [{ type: null }, { type: MATCH_LINE_TYPE }];
|
||||
const linesWithReferences = utils.addLineReferences(lines, lineNumbers, false, true, {
|
||||
old_line: 10,
|
||||
new_line: 11,
|
||||
});
|
||||
|
||||
expect(linesWithReferences[1].meta_data.old_pos).toEqual(10);
|
||||
expect(linesWithReferences[1].meta_data.new_pos).toEqual(11);
|
||||
});
|
||||
});
|
||||
|
||||
describe('trimFirstCharOfLineContent', () => {
|
||||
|
|
|
@ -39,6 +39,21 @@ describe Blobs::UnfoldPresenter do
|
|||
expect(result.indent).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when to is -1' do
|
||||
let(:params) { { full: false, since: 2, to: -1, bottom: true, offset: 1, indent: 1 } }
|
||||
|
||||
it 'sets other attributes' do
|
||||
result = subject
|
||||
|
||||
expect(result.full?).to eq(false)
|
||||
expect(result.since).to eq(2)
|
||||
expect(result.to).to eq(blob.lines.size)
|
||||
expect(result.bottom).to eq(false)
|
||||
expect(result.offset).to eq(0)
|
||||
expect(result.indent).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#diff_lines' do
|
||||
|
@ -83,8 +98,9 @@ describe Blobs::UnfoldPresenter do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when since is greater than 1' do
|
||||
let(:params) { { since: 5, to: 10, offset: 10 } }
|
||||
context 'when "since" is greater than 1' do
|
||||
let(:default_params) { { since: 5, to: 10, offset: 10 } }
|
||||
let(:params) { default_params }
|
||||
|
||||
it 'adds top match line' do
|
||||
line = subject.diff_lines.first
|
||||
|
@ -93,6 +109,38 @@ describe Blobs::UnfoldPresenter do
|
|||
expect(line.old_pos).to eq(5)
|
||||
expect(line.new_pos).to eq(5)
|
||||
end
|
||||
|
||||
context '"to" is higher than blob size' do
|
||||
let(:params) { default_params.merge(to: total_lines + 10, bottom: true) }
|
||||
|
||||
it 'does not add bottom match line' do
|
||||
line = subject.diff_lines.last
|
||||
|
||||
expect(line.type).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context '"to" is equal to blob size' do
|
||||
let(:params) { default_params.merge(to: total_lines, bottom: true) }
|
||||
|
||||
it 'does not add bottom match line' do
|
||||
line = subject.diff_lines.last
|
||||
|
||||
expect(line.type).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context '"to" is less than blob size' do
|
||||
let(:params) { default_params.merge(to: total_lines - 3, bottom: true) }
|
||||
|
||||
it 'adds bottom match line' do
|
||||
line = subject.diff_lines.last
|
||||
|
||||
expect(line.type).to eq('match')
|
||||
expect(line.old_pos).to eq(total_lines - 3 - params[:offset])
|
||||
expect(line.new_pos).to eq(total_lines - 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when "to" is less than blob size' do
|
||||
|
@ -116,6 +164,22 @@ describe Blobs::UnfoldPresenter do
|
|||
expect(line.type).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when "to" is "-1"' do
|
||||
let(:params) { { since: 10, to: -1, offset: 10, bottom: true } }
|
||||
|
||||
it 'does not add bottom match line' do
|
||||
line = subject.diff_lines.last
|
||||
|
||||
expect(line.type).to be_nil
|
||||
end
|
||||
|
||||
it 'last line is the latest blob line' do
|
||||
line = subject.diff_lines.last
|
||||
|
||||
expect(line.text).to eq(total_lines.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#lines' do
|
||||
|
|
Loading…
Reference in New Issue