diff options
Diffstat (limited to 'app/assets/javascripts/diffs')
15 files changed, 127 insertions, 14 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 77cd2afc106..3ea2a2fbaee 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -50,6 +50,11 @@ export default { type: String, required: true, }, + endpointCoverage: { + type: String, + required: false, + default: '', + }, projectPath: { type: String, required: true, @@ -169,6 +174,7 @@ export default { endpoint: this.endpoint, endpointMetadata: this.endpointMetadata, endpointBatch: this.endpointBatch, + endpointCoverage: this.endpointCoverage, projectPath: this.projectPath, dismissEndpoint: this.dismissEndpoint, showSuggestPopover: this.showSuggestPopover, @@ -218,6 +224,7 @@ export default { 'fetchDiffFiles', 'fetchDiffFilesMeta', 'fetchDiffFilesBatch', + 'fetchCoverageFiles', 'startRenderDiffsQueue', 'assignDiscussionsToDiff', 'setHighlightedRow', @@ -292,6 +299,10 @@ export default { }); } + if (this.endpointCoverage) { + this.fetchCoverageFiles(); + } + if (!this.isNotesFetched) { eventHub.$emit('fetchNotesData'); } diff --git a/app/assets/javascripts/diffs/components/diff_expansion_cell.vue b/app/assets/javascripts/diffs/components/diff_expansion_cell.vue index 4eae2e09c08..46ed76450c4 100644 --- a/app/assets/javascripts/diffs/components/diff_expansion_cell.vue +++ b/app/assets/javascripts/diffs/components/diff_expansion_cell.vue @@ -54,7 +54,7 @@ export default { colspan: { type: Number, required: false, - default: 3, + default: 4, }, }, computed: { diff --git a/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue b/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue index a06dbd70ac5..87f0396cf72 100644 --- a/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue +++ b/app/assets/javascripts/diffs/components/inline_diff_comment_row.vue @@ -51,7 +51,7 @@ export default { <template> <tr v-if="shouldRender" :class="className" class="notes_holder"> - <td class="notes-content" colspan="3"> + <td class="notes-content" colspan="4"> <div class="content"> <diff-discussions v-if="line.discussions.length" diff --git a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue index 55a8df43c62..bd99fcb71b8 100644 --- a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue +++ b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue @@ -1,5 +1,6 @@ <script> -import { mapActions, mapState } from 'vuex'; +import { mapActions, mapGetters, mapState } from 'vuex'; +import { GlTooltipDirective } from '@gitlab/ui'; import DiffTableCell from './diff_table_cell.vue'; import { MATCH_LINE_TYPE, @@ -15,11 +16,18 @@ export default { components: { DiffTableCell, }, + directives: { + GlTooltip: GlTooltipDirective, + }, props: { fileHash: { type: String, required: true, }, + filePath: { + type: String, + required: true, + }, contextLinesPath: { type: String, required: true, @@ -40,6 +48,7 @@ export default { }; }, computed: { + ...mapGetters('diffs', ['fileLineCoverage']), ...mapState({ isHighlighted(state) { return this.line.line_code !== null && this.line.line_code === state.diffs.highlightedRow; @@ -62,6 +71,9 @@ export default { isMatchLine() { return this.line.type === MATCH_LINE_TYPE; }, + coverageState() { + return this.fileLineCoverage(this.filePath, this.line.new_line); + }, }, created() { this.newLineType = NEW_LINE_TYPE; @@ -114,13 +126,19 @@ export default { class="diff-line-num new_line qa-new-diff-line" /> <td + v-gl-tooltip.hover + :title="coverageState.text" + :class="[line.type, coverageState.class, { hll: isHighlighted }]" + class="line-coverage" + ></td> + <td :class="[ line.type, { hll: isHighlighted, }, ]" - class="line_content" + class="line_content with-coverage" v-html="line.rich_text" ></td> </tr> diff --git a/app/assets/javascripts/diffs/components/inline_diff_view.vue b/app/assets/javascripts/diffs/components/inline_diff_view.vue index 1eb17588376..8b25cdc2887 100644 --- a/app/assets/javascripts/diffs/components/inline_diff_view.vue +++ b/app/assets/javascripts/diffs/components/inline_diff_view.vue @@ -48,6 +48,7 @@ export default { <colgroup> <col style="width: 50px;" /> <col style="width: 50px;" /> + <col style="width: 8px;" /> <col /> </colgroup> <tbody> @@ -63,6 +64,7 @@ export default { <inline-diff-table-row :key="`${line.line_code || index}`" :file-hash="diffFile.file_hash" + :file-path="diffFile.file_path" :context-lines-path="diffFile.context_lines_path" :line="line" :is-bottom="index + 1 === diffLinesLength" diff --git a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue index 65b41b0e456..b525490f7cc 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_comment_row.vue @@ -122,7 +122,7 @@ export default { <template> <tr v-if="shouldRender" :class="className" class="notes_holder"> - <td class="notes-content parallel old" colspan="2"> + <td class="notes-content parallel old" colspan="3"> <div v-if="shouldRenderDiscussionsOnLeft" class="content"> <diff-discussions :discussions="line.left.discussions" @@ -147,7 +147,7 @@ export default { </template> </diff-discussion-reply> </td> - <td class="notes-content parallel new" colspan="2"> + <td class="notes-content parallel new" colspan="3"> <div v-if="shouldRenderDiscussionsOnRight" class="content"> <diff-discussions :discussions="line.right.discussions" diff --git a/app/assets/javascripts/diffs/components/parallel_diff_expansion_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_expansion_row.vue index c1b30eab199..0a80107ced4 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_expansion_row.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_expansion_row.vue @@ -49,7 +49,7 @@ export default { :line="line.left" :is-top="isTop" :is-bottom="isBottom" - :colspan="4" + :colspan="6" /> </template> </tr> diff --git a/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue index 4c95d618b0f..83d803f42b1 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue @@ -1,6 +1,7 @@ <script> -import { mapActions, mapState } from 'vuex'; +import { mapActions, mapGetters, mapState } from 'vuex'; import $ from 'jquery'; +import { GlTooltipDirective } from '@gitlab/ui'; import DiffTableCell from './diff_table_cell.vue'; import { MATCH_LINE_TYPE, @@ -18,11 +19,18 @@ export default { components: { DiffTableCell, }, + directives: { + GlTooltip: GlTooltipDirective, + }, props: { fileHash: { type: String, required: true, }, + filePath: { + type: String, + required: true, + }, contextLinesPath: { type: String, required: true, @@ -44,6 +52,7 @@ export default { }; }, computed: { + ...mapGetters('diffs', ['fileLineCoverage']), ...mapState({ isHighlighted(state) { const lineCode = @@ -82,6 +91,9 @@ export default { isMatchLineRight() { return this.line.right && this.line.right.type === MATCH_LINE_TYPE; }, + coverageState() { + return this.fileLineCoverage(this.filePath, this.line.right.new_line); + }, }, created() { this.newLineType = NEW_LINE_TYPE; @@ -99,7 +111,7 @@ export default { const allCellsInHoveringRow = Array.from(e.currentTarget.children); const hoverIndex = allCellsInHoveringRow.indexOf(hoveringCell); - if (hoverIndex >= 2) { + if (hoverIndex >= 3) { this.isRightHover = isHover; } else { this.isLeftHover = isHover; @@ -143,17 +155,19 @@ export default { line-position="left" class="diff-line-num old_line" /> + <td :class="parallelViewLeftLineType" class="line-coverage left-side"></td> <td :id="line.left.line_code" :class="parallelViewLeftLineType" - class="line_content parallel left-side" + class="line_content with-coverage parallel left-side" @mousedown="handleParallelLineMouseDown" v-html="line.left.rich_text" ></td> </template> <template v-else> <td class="diff-line-num old_line empty-cell"></td> - <td class="line_content parallel left-side empty-cell"></td> + <td class="line-coverage left-side empty-cell"></td> + <td class="line_content with-coverage parallel left-side empty-cell"></td> </template> <template v-if="line.right && !isMatchLineRight"> <diff-table-cell @@ -170,6 +184,12 @@ export default { class="diff-line-num new_line" /> <td + v-gl-tooltip.hover + :title="coverageState.text" + :class="[line.right.type, coverageState.class, { hll: isHighlighted }]" + class="line-coverage right-side" + ></td> + <td :id="line.right.line_code" :class="[ line.right.type, @@ -177,14 +197,15 @@ export default { hll: isHighlighted, }, ]" - class="line_content parallel right-side" + class="line_content with-coverage parallel right-side" @mousedown="handleParallelLineMouseDown" v-html="line.right.rich_text" ></td> </template> <template v-else> <td class="diff-line-num old_line empty-cell"></td> - <td class="line_content parallel right-side empty-cell"></td> + <td class="line-coverage right-side empty-cell"></td> + <td class="line_content with-coverage parallel right-side empty-cell"></td> </template> </tr> </template> diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue index 88baac092a1..d796aad9d06 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue @@ -47,8 +47,10 @@ export default { > <colgroup> <col style="width: 50px;" /> + <col style="width: 8px;" /> <col /> <col style="width: 50px;" /> + <col style="width: 8px;" /> <col /> </colgroup> <tbody> @@ -64,6 +66,7 @@ export default { <parallel-diff-table-row :key="line.line_code" :file-hash="diffFile.file_hash" + :file-path="diffFile.file_path" :context-lines-path="diffFile.context_lines_path" :line="line" :is-bottom="index + 1 === diffLinesLength" diff --git a/app/assets/javascripts/diffs/index.js b/app/assets/javascripts/diffs/index.js index 375ac80021f..ce48e36bfd7 100644 --- a/app/assets/javascripts/diffs/index.js +++ b/app/assets/javascripts/diffs/index.js @@ -69,6 +69,7 @@ export default function initDiffsApp(store) { endpoint: dataset.endpoint, endpointMetadata: dataset.endpointMetadata || '', endpointBatch: dataset.endpointBatch || '', + endpointCoverage: dataset.endpointCoverage || '', projectPath: dataset.projectPath, helpPagePath: dataset.helpPagePath, currentUser: JSON.parse(dataset.currentUserData) || {}, @@ -104,6 +105,7 @@ export default function initDiffsApp(store) { endpoint: this.endpoint, endpointMetadata: this.endpointMetadata, endpointBatch: this.endpointBatch, + endpointCoverage: this.endpointCoverage, currentUser: this.currentUser, projectPath: this.projectPath, helpPagePath: this.helpPagePath, diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index bd85105ccb4..18bbdf402ee 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -1,8 +1,10 @@ import Vue from 'vue'; import Cookies from 'js-cookie'; +import Poll from '~/lib/utils/poll'; import axios from '~/lib/utils/axios_utils'; +import httpStatusCodes from '~/lib/utils/http_status'; import createFlash from '~/flash'; -import { s__ } from '~/locale'; +import { __, s__ } from '~/locale'; import { handleLocationHash, historyPushState, scrollToElement } from '~/lib/utils/common_utils'; import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility'; import TreeWorker from '../workers/tree_worker'; @@ -43,6 +45,7 @@ export const setBaseConfig = ({ commit }, options) => { endpoint, endpointMetadata, endpointBatch, + endpointCoverage, projectPath, dismissEndpoint, showSuggestPopover, @@ -52,6 +55,7 @@ export const setBaseConfig = ({ commit }, options) => { endpoint, endpointMetadata, endpointBatch, + endpointCoverage, projectPath, dismissEndpoint, showSuggestPopover, @@ -170,6 +174,26 @@ export const fetchDiffFilesMeta = ({ commit, state }) => { .catch(() => worker.terminate()); }; +export const fetchCoverageFiles = ({ commit, state }) => { + const coveragePoll = new Poll({ + resource: { + getCoverageReports: endpoint => axios.get(endpoint), + }, + data: state.endpointCoverage, + method: 'getCoverageReports', + successCallback: ({ status, data }) => { + if (status === httpStatusCodes.OK) { + commit(types.SET_COVERAGE_DATA, data); + + coveragePoll.stop(); + } + }, + errorCallback: () => createFlash(__('Something went wrong on our end. Please try again!')), + }); + + coveragePoll.makeRequest(); +}; + export const setHighlightedRow = ({ commit }, lineCode) => { const fileHash = lineCode.split('_')[0]; commit(types.SET_HIGHLIGHTED_ROW, lineCode); diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js index c4737090a70..3898974638f 100644 --- a/app/assets/javascripts/diffs/store/getters.js +++ b/app/assets/javascripts/diffs/store/getters.js @@ -1,3 +1,4 @@ +import { __, n__ } from '~/locale'; import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '../constants'; export const isParallelView = state => state.diffViewType === PARALLEL_DIFF_VIEW_TYPE; @@ -99,6 +100,29 @@ export const getCommentFormForDiffFile = state => fileHash => state.commentForms.find(form => form.fileHash === fileHash); /** + * Returns the test coverage hits for a specific line of a given file + * @param {string} file + * @param {number} line + * @returns {number} + */ +export const fileLineCoverage = state => (file, line) => { + if (!state.coverageFiles.files) return {}; + const fileCoverage = state.coverageFiles.files[file]; + if (!fileCoverage) return {}; + const lineCoverage = fileCoverage[String(line)]; + + if (lineCoverage === 0) { + return { text: __('No test coverage'), class: 'no-coverage' }; + } else if (lineCoverage >= 0) { + return { + text: n__('Test coverage: %d hit', 'Test coverage: %d hits', lineCoverage), + class: 'coverage', + }; + } + return {}; +}; + +/** * Returns index of a currently selected diff in diffFiles * @returns {number} */ diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js index 011cd24500a..81f1506260c 100644 --- a/app/assets/javascripts/diffs/store/modules/diff_state.js +++ b/app/assets/javascripts/diffs/store/modules/diff_state.js @@ -17,6 +17,7 @@ export default () => ({ commit: null, startVersion: null, diffFiles: [], + coverageFiles: {}, mergeRequestDiffs: [], mergeRequestDiff: null, diffViewType: viewTypeFromQueryString || viewTypeFromCookie || defaultViewType, diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js index 2097c8d3655..4436935c1ec 100644 --- a/app/assets/javascripts/diffs/store/mutation_types.js +++ b/app/assets/javascripts/diffs/store/mutation_types.js @@ -5,6 +5,7 @@ export const SET_RETRIEVING_BATCHES = 'SET_RETRIEVING_BATCHES'; export const SET_DIFF_DATA = 'SET_DIFF_DATA'; export const SET_DIFF_DATA_BATCH = 'SET_DIFF_DATA_BATCH'; export const SET_DIFF_VIEW_TYPE = 'SET_DIFF_VIEW_TYPE'; +export const SET_COVERAGE_DATA = 'SET_COVERAGE_DATA'; export const SET_MERGE_REQUEST_DIFFS = 'SET_MERGE_REQUEST_DIFFS'; export const TOGGLE_LINE_HAS_FORM = 'TOGGLE_LINE_HAS_FORM'; export const ADD_CONTEXT_LINES = 'ADD_CONTEXT_LINES'; diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js index 086a7872a5d..bb4c80b5759 100644 --- a/app/assets/javascripts/diffs/store/mutations.js +++ b/app/assets/javascripts/diffs/store/mutations.js @@ -16,6 +16,7 @@ export default { endpoint, endpointMetadata, endpointBatch, + endpointCoverage, projectPath, dismissEndpoint, showSuggestPopover, @@ -25,6 +26,7 @@ export default { endpoint, endpointMetadata, endpointBatch, + endpointCoverage, projectPath, dismissEndpoint, showSuggestPopover, @@ -69,6 +71,10 @@ export default { }); }, + [types.SET_COVERAGE_DATA](state, coverageFiles) { + Object.assign(state, { coverageFiles }); + }, + [types.RENDER_FILE](state, file) { Object.assign(file, { renderIt: true, |