From 80f61b4035607d7cd87de993b8f5e996bde3481f Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 18 Sep 2019 14:02:45 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../jobs/components/log/duration_badge_spec.js | 31 +++++ .../jobs/components/log/line_header_spec.js | 95 +++++++++++++ .../jobs/components/log/line_number_spec.js | 40 ++++++ spec/frontend/jobs/components/log/line_spec.js | 49 +++++++ spec/frontend/jobs/components/log/log_spec.js | 77 +++++++++++ spec/frontend/jobs/components/log/mock_data.js | 152 ++++++++++++++++++++ spec/frontend/jobs/store/utils_spec.js | 153 ++++----------------- 7 files changed, 467 insertions(+), 130 deletions(-) create mode 100644 spec/frontend/jobs/components/log/duration_badge_spec.js create mode 100644 spec/frontend/jobs/components/log/line_header_spec.js create mode 100644 spec/frontend/jobs/components/log/line_number_spec.js create mode 100644 spec/frontend/jobs/components/log/line_spec.js create mode 100644 spec/frontend/jobs/components/log/log_spec.js create mode 100644 spec/frontend/jobs/components/log/mock_data.js (limited to 'spec/frontend/jobs') diff --git a/spec/frontend/jobs/components/log/duration_badge_spec.js b/spec/frontend/jobs/components/log/duration_badge_spec.js new file mode 100644 index 00000000000..2ac34e78909 --- /dev/null +++ b/spec/frontend/jobs/components/log/duration_badge_spec.js @@ -0,0 +1,31 @@ +import { shallowMount } from '@vue/test-utils'; +import DurationBadge from '~/jobs/components/log/duration_badge.vue'; + +describe('Job Log Duration Badge', () => { + let wrapper; + + const data = { + duration: '00:30:01', + }; + + const createComponent = (props = {}) => { + wrapper = shallowMount(DurationBadge, { + sync: false, + propsData: { + ...props, + }, + }); + }; + + beforeEach(() => { + createComponent(data); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders provided duration', () => { + expect(wrapper.text()).toBe(data.duration); + }); +}); diff --git a/spec/frontend/jobs/components/log/line_header_spec.js b/spec/frontend/jobs/components/log/line_header_spec.js new file mode 100644 index 00000000000..2d2f92fad9d --- /dev/null +++ b/spec/frontend/jobs/components/log/line_header_spec.js @@ -0,0 +1,95 @@ +import { mount } from '@vue/test-utils'; +import LineHeader from '~/jobs/components/log/line_header.vue'; +import LineNumber from '~/jobs/components/log/line_number.vue'; +import DurationBadge from '~/jobs/components/log/duration_badge.vue'; + +describe('Job Log Header Line', () => { + let wrapper; + + const data = { + line: { + content: [ + { + text: 'Running with gitlab-runner 12.1.0 (de7731dd)', + style: 'term-fg-l-green', + }, + ], + lineNumber: 0, + }, + isClosed: true, + path: '/jashkenas/underscore/-/jobs/335', + }; + + const createComponent = (props = {}) => { + wrapper = mount(LineHeader, { + sync: false, + propsData: { + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + describe('line', () => { + beforeEach(() => { + createComponent(data); + }); + + it('renders the line number component', () => { + expect(wrapper.contains(LineNumber)).toBe(true); + }); + + it('renders a span the provided text', () => { + expect(wrapper.find('span').text()).toBe(data.line.content[0].text); + }); + + it('renders the provided style as a class attribute', () => { + expect(wrapper.find('span').classes()).toContain(data.line.content[0].style); + }); + }); + + describe('when isCloses is true', () => { + beforeEach(() => { + createComponent({ ...data, isClosed: true }); + }); + + it('sets icon name to be angle-right', () => { + expect(wrapper.vm.iconName).toEqual('angle-right'); + }); + }); + + describe('when isCloses is false', () => { + beforeEach(() => { + createComponent({ ...data, isClosed: false }); + }); + + it('sets icon name to be angle-down', () => { + expect(wrapper.vm.iconName).toEqual('angle-down'); + }); + }); + + describe('on click', () => { + beforeEach(() => { + createComponent(data); + }); + + it('emits toggleLine event', () => { + wrapper.trigger('click'); + + expect(wrapper.emitted().toggleLine.length).toBe(1); + }); + }); + + describe('with duration', () => { + beforeEach(() => { + createComponent(Object.assign({}, data, { duration: '00:10' })); + }); + + it('renders the duration badge', () => { + expect(wrapper.contains(DurationBadge)).toBe(true); + }); + }); +}); diff --git a/spec/frontend/jobs/components/log/line_number_spec.js b/spec/frontend/jobs/components/log/line_number_spec.js new file mode 100644 index 00000000000..fcf2edf9159 --- /dev/null +++ b/spec/frontend/jobs/components/log/line_number_spec.js @@ -0,0 +1,40 @@ +import { shallowMount } from '@vue/test-utils'; +import LineNumber from '~/jobs/components/log/line_number.vue'; + +describe('Job Log Line Number', () => { + let wrapper; + + const data = { + lineNumber: 0, + path: '/jashkenas/underscore/-/jobs/335', + }; + + const createComponent = (props = {}) => { + wrapper = shallowMount(LineNumber, { + sync: false, + propsData: { + ...props, + }, + }); + }; + + beforeEach(() => { + createComponent(data); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders incremented lineNunber by 1', () => { + expect(wrapper.text()).toBe('1'); + }); + + it('renders link with lineNumber as an ID', () => { + expect(wrapper.attributes().id).toBe('L1'); + }); + + it('links to the provided path with line number as anchor', () => { + expect(wrapper.attributes().href).toBe(`${data.path}#L1`); + }); +}); diff --git a/spec/frontend/jobs/components/log/line_spec.js b/spec/frontend/jobs/components/log/line_spec.js new file mode 100644 index 00000000000..ea593e3c39a --- /dev/null +++ b/spec/frontend/jobs/components/log/line_spec.js @@ -0,0 +1,49 @@ +import { shallowMount } from '@vue/test-utils'; +import Line from '~/jobs/components/log/line.vue'; +import LineNumber from '~/jobs/components/log/line_number.vue'; + +describe('Job Log Line', () => { + let wrapper; + + const data = { + line: { + content: [ + { + text: 'Running with gitlab-runner 12.1.0 (de7731dd)', + style: 'term-fg-l-green', + }, + ], + lineNumber: 0, + }, + path: '/jashkenas/underscore/-/jobs/335', + }; + + const createComponent = (props = {}) => { + wrapper = shallowMount(Line, { + sync: false, + propsData: { + ...props, + }, + }); + }; + + beforeEach(() => { + createComponent(data); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders the line number component', () => { + expect(wrapper.contains(LineNumber)).toBe(true); + }); + + it('renders a span the provided text', () => { + expect(wrapper.find('span').text()).toBe(data.line.content[0].text); + }); + + it('renders the provided style as a class attribute', () => { + expect(wrapper.find('span').classes()).toContain(data.line.content[0].style); + }); +}); diff --git a/spec/frontend/jobs/components/log/log_spec.js b/spec/frontend/jobs/components/log/log_spec.js new file mode 100644 index 00000000000..cc334009982 --- /dev/null +++ b/spec/frontend/jobs/components/log/log_spec.js @@ -0,0 +1,77 @@ +import { mount, createLocalVue } from '@vue/test-utils'; +import Vuex from 'vuex'; +import { logLinesParser } from '~/jobs/store/utils'; +import Log from '~/jobs/components/log/log.vue'; +import { jobLog } from './mock_data'; + +describe('Job Log', () => { + let wrapper; + let actions; + let state; + let store; + + const localVue = createLocalVue(); + localVue.use(Vuex); + + const createComponent = () => { + wrapper = mount(Log, { + sync: false, + localVue, + store, + }); + }; + + beforeEach(() => { + actions = { + toggleCollapsibleLine: () => {}, + }; + + state = { + trace: logLinesParser(jobLog), + traceEndpoint: 'jobs/id', + }; + + store = new Vuex.Store({ + actions, + state, + }); + + createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('line numbers', () => { + it('renders a line number for each open line', () => { + expect(wrapper.find('#L1').text()).toBe('1'); + expect(wrapper.find('#L2').text()).toBe('2'); + expect(wrapper.find('#L3').text()).toBe('3'); + }); + + it('links to the provided path and correct line number', () => { + expect(wrapper.find('#L1').attributes('href')).toBe(`${state.traceEndpoint}#L1`); + }); + }); + + describe('collapsible sections', () => { + it('renders a clickable header section', () => { + expect(wrapper.find('.collapsible-line').attributes('role')).toBe('button'); + }); + + it('renders an icon with the closed state', () => { + expect(wrapper.find('.collapsible-line svg').classes()).toContain('ic-angle-right'); + }); + + describe('on click header section', () => { + it('calls toggleCollapsibleLine', () => { + jest.spyOn(wrapper.vm, 'toggleCollapsibleLine'); + + wrapper.find('.collapsible-line').trigger('click'); + + expect(wrapper.vm.toggleCollapsibleLine).toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/spec/frontend/jobs/components/log/mock_data.js b/spec/frontend/jobs/components/log/mock_data.js new file mode 100644 index 00000000000..db42644de77 --- /dev/null +++ b/spec/frontend/jobs/components/log/mock_data.js @@ -0,0 +1,152 @@ +export const jobLog = [ + { + offset: 1000, + content: [{ text: 'Running with gitlab-runner 12.1.0 (de7731dd)' }], + }, + { + offset: 1001, + content: [{ text: ' on docker-auto-scale-com 8a6210b8' }], + }, + { + offset: 1002, + content: [ + { + text: 'Using Docker executor with image dev.gitlab.org3', + }, + ], + sections: ['prepare-executor'], + section_header: true, + }, + { + offset: 1003, + content: [{ text: 'Starting service postgres:9.6.14 ...', style: 'text-green' }], + sections: ['prepare-executor'], + }, +]; + +export const utilsMockData = [ + { + offset: 1001, + content: [{ text: ' on docker-auto-scale-com 8a6210b8' }], + }, + { + offset: 1002, + content: [ + { + text: + 'Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33', + }, + ], + sections: ['prepare-executor'], + section_header: true, + }, + { + offset: 1003, + content: [{ text: 'Starting service postgres:9.6.14 ...' }], + sections: ['prepare-executor'], + }, + { + offset: 1004, + content: [{ text: 'Pulling docker image postgres:9.6.14 ...', style: 'term-fg-l-green' }], + sections: ['prepare-executor'], + }, + { + offset: 1005, + content: [], + sections: ['prepare-executor'], + section_duration: '10:00', + }, +]; + +export const originalTrace = [ + { + offset: 1, + content: [ + { + text: 'Downloading', + }, + ], + }, +]; + +export const regularIncremental = [ + { + offset: 2, + content: [ + { + text: 'log line', + }, + ], + }, +]; + +export const regularIncrementalRepeated = [ + { + offset: 1, + content: [ + { + text: 'log line', + }, + ], + }, +]; + +export const headerTrace = [ + { + offset: 1, + section_header: true, + content: [ + { + text: 'log line', + }, + ], + sections: ['section'], + }, +]; + +export const headerTraceIncremental = [ + { + offset: 1, + section_header: true, + content: [ + { + text: 'updated log line', + }, + ], + sections: ['section'], + }, +]; + +export const collapsibleTrace = [ + { + offset: 1, + section_header: true, + content: [ + { + text: 'log line', + }, + ], + sections: ['section'], + }, + { + offset: 2, + content: [ + { + text: 'log line', + }, + ], + sections: ['section'], + }, +]; + +export const collapsibleTraceIncremental = [ + { + offset: 2, + content: [ + { + text: 'updated log line', + }, + ], + sections: ['section'], + }, +]; diff --git a/spec/frontend/jobs/store/utils_spec.js b/spec/frontend/jobs/store/utils_spec.js index 7b484ccfa07..780d42fd6a1 100644 --- a/spec/frontend/jobs/store/utils_spec.js +++ b/spec/frontend/jobs/store/utils_spec.js @@ -1,45 +1,21 @@ import { logLinesParser, updateIncrementalTrace } from '~/jobs/store/utils'; +import { + utilsMockData, + originalTrace, + regularIncremental, + regularIncrementalRepeated, + headerTrace, + headerTraceIncremental, + collapsibleTrace, + collapsibleTraceIncremental, +} from '../components/log/mock_data'; describe('Jobs Store Utils', () => { describe('logLinesParser', () => { - const mockData = [ - { - offset: 1001, - content: [{ text: ' on docker-auto-scale-com 8a6210b8' }], - }, - { - offset: 1002, - content: [ - { - text: - 'Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33', - }, - ], - sections: ['prepare-executor'], - section_header: true, - }, - { - offset: 1003, - content: [{ text: 'Starting service postgres:9.6.14 ...' }], - sections: ['prepare-executor'], - }, - { - offset: 1004, - content: [{ text: 'Pulling docker image postgres:9.6.14 ...', style: 'term-fg-l-green' }], - sections: ['prepare-executor'], - }, - { - offset: 1005, - content: [], - sections: ['prepare-executor'], - section_duration: '10:00', - }, - ]; - let result; beforeEach(() => { - result = logLinesParser(mockData); + result = logLinesParser(utilsMockData); }); describe('regular line', () => { @@ -60,48 +36,27 @@ describe('Jobs Store Utils', () => { it('creates a lines array property with the content of the collpasible section', () => { expect(result[1].lines.length).toEqual(2); - expect(result[1].lines[0].content).toEqual(mockData[2].content); - expect(result[1].lines[1].content).toEqual(mockData[3].content); + expect(result[1].lines[0].content).toEqual(utilsMockData[2].content); + expect(result[1].lines[1].content).toEqual(utilsMockData[3].content); }); }); describe('section duration', () => { it('adds the section information to the header section', () => { - expect(result[1].section_duration).toEqual(mockData[4].section_duration); + expect(result[1].section_duration).toEqual(utilsMockData[4].section_duration); }); it('does not add section duration as a line', () => { - expect(result[1].lines.includes(mockData[4])).toEqual(false); + expect(result[1].lines.includes(utilsMockData[4])).toEqual(false); }); }); }); describe('updateIncrementalTrace', () => { - const originalTrace = [ - { - offset: 1, - content: [ - { - text: 'Downloading', - }, - ], - }, - ]; - describe('without repeated section', () => { it('concats and parses both arrays', () => { const oldLog = logLinesParser(originalTrace); - const newLog = [ - { - offset: 2, - content: [ - { - text: 'log line', - }, - ], - }, - ]; - const result = updateIncrementalTrace(originalTrace, oldLog, newLog); + const result = updateIncrementalTrace(originalTrace, oldLog, regularIncremental); expect(result).toEqual([ { @@ -129,17 +84,7 @@ describe('Jobs Store Utils', () => { describe('with regular line repeated offset', () => { it('updates the last line and formats with the incremental part', () => { const oldLog = logLinesParser(originalTrace); - const newLog = [ - { - offset: 1, - content: [ - { - text: 'log line', - }, - ], - }, - ]; - const result = updateIncrementalTrace(originalTrace, oldLog, newLog); + const result = updateIncrementalTrace(originalTrace, oldLog, regularIncrementalRepeated); expect(result).toEqual([ { @@ -157,32 +102,8 @@ describe('Jobs Store Utils', () => { describe('with header line repeated', () => { it('updates the header line and formats with the incremental part', () => { - const headerTrace = [ - { - offset: 1, - section_header: true, - content: [ - { - text: 'log line', - }, - ], - sections: ['section'], - }, - ]; const oldLog = logLinesParser(headerTrace); - const newLog = [ - { - offset: 1, - section_header: true, - content: [ - { - text: 'updated log line', - }, - ], - sections: ['section'], - }, - ]; - const result = updateIncrementalTrace(headerTrace, oldLog, newLog); + const result = updateIncrementalTrace(headerTrace, oldLog, headerTraceIncremental); expect(result).toEqual([ { @@ -207,40 +128,12 @@ describe('Jobs Store Utils', () => { describe('with collapsible line repeated', () => { it('updates the collapsible line and formats with the incremental part', () => { - const collapsibleTrace = [ - { - offset: 1, - section_header: true, - content: [ - { - text: 'log line', - }, - ], - sections: ['section'], - }, - { - offset: 2, - content: [ - { - text: 'log line', - }, - ], - sections: ['section'], - }, - ]; const oldLog = logLinesParser(collapsibleTrace); - const newLog = [ - { - offset: 2, - content: [ - { - text: 'updated log line', - }, - ], - sections: ['section'], - }, - ]; - const result = updateIncrementalTrace(collapsibleTrace, oldLog, newLog); + const result = updateIncrementalTrace( + collapsibleTrace, + oldLog, + collapsibleTraceIncremental, + ); expect(result).toEqual([ { -- cgit v1.2.3