Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/ml/experiment_tracking/routes/candidates')
-rw-r--r--spec/frontend/ml/experiment_tracking/routes/candidates/show/components/candidate_detail_row_spec.js11
-rw-r--r--spec/frontend/ml/experiment_tracking/routes/candidates/show/ml_candidates_show_spec.js138
-rw-r--r--spec/frontend/ml/experiment_tracking/routes/candidates/show/mock_data.js7
3 files changed, 86 insertions, 70 deletions
diff --git a/spec/frontend/ml/experiment_tracking/routes/candidates/show/components/candidate_detail_row_spec.js b/spec/frontend/ml/experiment_tracking/routes/candidates/show/components/candidate_detail_row_spec.js
index 53dbd796d85..cd252560590 100644
--- a/spec/frontend/ml/experiment_tracking/routes/candidates/show/components/candidate_detail_row_spec.js
+++ b/spec/frontend/ml/experiment_tracking/routes/candidates/show/components/candidate_detail_row_spec.js
@@ -2,15 +2,14 @@ import { shallowMount } from '@vue/test-utils';
import DetailRow from '~/ml/experiment_tracking/routes/candidates/show/components/candidate_detail_row.vue';
describe('CandidateDetailRow', () => {
- const SECTION_LABEL_CELL = 0;
- const ROW_LABEL_CELL = 1;
- const ROW_VALUE_CELL = 2;
+ const ROW_LABEL_CELL = 0;
+ const ROW_VALUE_CELL = 1;
let wrapper;
const createWrapper = ({ slots = {} } = {}) => {
wrapper = shallowMount(DetailRow, {
- propsData: { sectionLabel: 'Section', label: 'Item' },
+ propsData: { label: 'Item' },
slots,
});
};
@@ -19,10 +18,6 @@ describe('CandidateDetailRow', () => {
beforeEach(() => createWrapper());
- it('renders section label', () => {
- expect(findCellAt(SECTION_LABEL_CELL).text()).toBe('Section');
- });
-
it('renders row label', () => {
expect(findCellAt(ROW_LABEL_CELL).text()).toBe('Item');
});
diff --git a/spec/frontend/ml/experiment_tracking/routes/candidates/show/ml_candidates_show_spec.js b/spec/frontend/ml/experiment_tracking/routes/candidates/show/ml_candidates_show_spec.js
index 0b3b780cb3f..296728af46a 100644
--- a/spec/frontend/ml/experiment_tracking/routes/candidates/show/ml_candidates_show_spec.js
+++ b/spec/frontend/ml/experiment_tracking/routes/candidates/show/ml_candidates_show_spec.js
@@ -1,32 +1,51 @@
-import { shallowMount } from '@vue/test-utils';
-import { GlAvatarLabeled, GlLink } from '@gitlab/ui';
+import { GlAvatarLabeled, GlLink, GlTableLite } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import MlCandidatesShow from '~/ml/experiment_tracking/routes/candidates/show';
import DetailRow from '~/ml/experiment_tracking/routes/candidates/show/components/candidate_detail_row.vue';
-import { TITLE_LABEL } from '~/ml/experiment_tracking/routes/candidates/show/translations';
+import {
+ TITLE_LABEL,
+ NO_PARAMETERS_MESSAGE,
+ NO_METRICS_MESSAGE,
+ NO_METADATA_MESSAGE,
+ NO_CI_MESSAGE,
+} from '~/ml/experiment_tracking/routes/candidates/show/translations';
import DeleteButton from '~/ml/experiment_tracking/components/delete_button.vue';
import ModelExperimentsHeader from '~/ml/experiment_tracking/components/model_experiments_header.vue';
+import { stubComponent } from 'helpers/stub_component';
import { newCandidate } from './mock_data';
describe('MlCandidatesShow', () => {
let wrapper;
const CANDIDATE = newCandidate();
- const USER_ROW = 6;
+ const USER_ROW = 1;
+
+ const INFO_SECTION = 0;
+ const CI_SECTION = 1;
+ const PARAMETER_SECTION = 2;
+ const METADATA_SECTION = 3;
const createWrapper = (createCandidate = () => CANDIDATE) => {
- wrapper = shallowMount(MlCandidatesShow, {
+ wrapper = shallowMountExtended(MlCandidatesShow, {
propsData: { candidate: createCandidate() },
+ stubs: {
+ GlTableLite: { ...stubComponent(GlTableLite), props: ['items', 'fields'] },
+ },
});
};
const findDeleteButton = () => wrapper.findComponent(DeleteButton);
const findHeader = () => wrapper.findComponent(ModelExperimentsHeader);
- const findNthDetailRow = (index) => wrapper.findAllComponents(DetailRow).at(index);
- const findLinkInNthDetailRow = (index) => findNthDetailRow(index).findComponent(GlLink);
- const findSectionLabel = (label) => wrapper.find(`[sectionLabel='${label}']`);
+ const findSection = (section) => wrapper.findAll('section').at(section);
+ const findRowInSection = (section, row) =>
+ findSection(section).findAllComponents(DetailRow).at(row);
+ const findLinkAtRow = (section, rowIndex) =>
+ findRowInSection(section, rowIndex).findComponent(GlLink);
+ const findNoDataMessage = (label) => wrapper.findByText(label);
const findLabel = (label) => wrapper.find(`[label='${label}']`);
- const findCiUserDetailRow = () => findNthDetailRow(USER_ROW);
+ const findCiUserDetailRow = () => findRowInSection(CI_SECTION, USER_ROW);
const findCiUserAvatar = () => findCiUserDetailRow().findComponent(GlAvatarLabeled);
const findCiUserAvatarNameLink = () => findCiUserAvatar().findComponent(GlLink);
+ const findMetricsTable = () => wrapper.findComponent(GlTableLite);
describe('Header', () => {
beforeEach(() => createWrapper());
@@ -50,42 +69,57 @@ describe('MlCandidatesShow', () => {
const mrText = `!${CANDIDATE.info.ci_job.merge_request.iid} ${CANDIDATE.info.ci_job.merge_request.title}`;
const expectedTable = [
- ['Info', 'ID', CANDIDATE.info.iid],
- ['', 'MLflow run ID', CANDIDATE.info.eid],
- ['', 'Status', CANDIDATE.info.status],
- ['', 'Experiment', CANDIDATE.info.experiment_name],
- ['', 'Artifacts', 'Artifacts'],
- ['CI', 'Job', CANDIDATE.info.ci_job.name],
- ['', 'Triggered by', 'CI User'],
- ['', 'Merge request', mrText],
- ['Parameters', CANDIDATE.params[0].name, CANDIDATE.params[0].value],
- ['', CANDIDATE.params[1].name, CANDIDATE.params[1].value],
- ['Metrics', CANDIDATE.metrics[0].name, CANDIDATE.metrics[0].value],
- ['', CANDIDATE.metrics[1].name, CANDIDATE.metrics[1].value],
- ['Metadata', CANDIDATE.metadata[0].name, CANDIDATE.metadata[0].value],
- ['', CANDIDATE.metadata[1].name, CANDIDATE.metadata[1].value],
- ].map((row, index) => [index, ...row]);
-
- it.each(expectedTable)(
- 'row %s is created correctly',
- (rowIndex, sectionLabel, label, text) => {
- const row = findNthDetailRow(rowIndex);
-
- expect(row.props()).toMatchObject({ sectionLabel, label });
- expect(row.text()).toBe(text);
- },
- );
+ [INFO_SECTION, 0, 'ID', CANDIDATE.info.iid],
+ [INFO_SECTION, 1, 'MLflow run ID', CANDIDATE.info.eid],
+ [INFO_SECTION, 2, 'Status', CANDIDATE.info.status],
+ [INFO_SECTION, 3, 'Experiment', CANDIDATE.info.experiment_name],
+ [INFO_SECTION, 4, 'Artifacts', 'Artifacts'],
+ [CI_SECTION, 0, 'Job', CANDIDATE.info.ci_job.name],
+ [CI_SECTION, 1, 'Triggered by', 'CI User'],
+ [CI_SECTION, 2, 'Merge request', mrText],
+ [PARAMETER_SECTION, 0, CANDIDATE.params[0].name, CANDIDATE.params[0].value],
+ [PARAMETER_SECTION, 1, CANDIDATE.params[1].name, CANDIDATE.params[1].value],
+ [METADATA_SECTION, 0, CANDIDATE.metadata[0].name, CANDIDATE.metadata[0].value],
+ [METADATA_SECTION, 1, CANDIDATE.metadata[1].name, CANDIDATE.metadata[1].value],
+ ];
+
+ it.each(expectedTable)('row %s is created correctly', (section, rowIndex, label, text) => {
+ const row = findRowInSection(section, rowIndex);
+
+ expect(row.props()).toMatchObject({ label });
+ expect(row.text()).toBe(text);
+ });
describe('Table links', () => {
const linkRows = [
- [3, CANDIDATE.info.path_to_experiment],
- [4, CANDIDATE.info.path_to_artifact],
- [5, CANDIDATE.info.ci_job.path],
- [7, CANDIDATE.info.ci_job.merge_request.path],
+ [INFO_SECTION, 3, CANDIDATE.info.path_to_experiment],
+ [INFO_SECTION, 4, CANDIDATE.info.path_to_artifact],
+ [CI_SECTION, 0, CANDIDATE.info.ci_job.path],
+ [CI_SECTION, 2, CANDIDATE.info.ci_job.merge_request.path],
];
- it.each(linkRows)('row %s is created correctly', (rowIndex, href) => {
- expect(findLinkInNthDetailRow(rowIndex).attributes().href).toBe(href);
+ it.each(linkRows)('row %s is created correctly', (section, rowIndex, href) => {
+ expect(findLinkAtRow(section, rowIndex).attributes().href).toBe(href);
+ });
+ });
+
+ describe('Metrics table', () => {
+ it('computes metrics table items correctly', () => {
+ expect(findMetricsTable().props('items')).toEqual([
+ { name: 'AUC', 0: '.55' },
+ { name: 'Accuracy', 1: '.99', 2: '.98', 3: '.97' },
+ { name: 'F1', 3: '.1' },
+ ]);
+ });
+
+ it('computes metrics table fields correctly', () => {
+ expect(findMetricsTable().props('fields')).toEqual([
+ expect.objectContaining({ key: 'name', label: 'Metric' }),
+ expect.objectContaining({ key: '0', label: 'Step 0' }),
+ expect.objectContaining({ key: '1', label: 'Step 1' }),
+ expect.objectContaining({ key: '2', label: 'Step 2' }),
+ expect.objectContaining({ key: '3', label: 'Step 3' }),
+ ]);
});
});
@@ -105,22 +139,6 @@ describe('MlCandidatesShow', () => {
expect(nameLink.text()).toEqual('CI User');
});
});
-
- it('does not render params', () => {
- expect(findSectionLabel('Parameters').exists()).toBe(true);
- });
-
- it('renders all conditional rows', () => {
- // This is a bit of a duplicated test from the above table test, but having this makes sure that the
- // tests that test the negatives are implemented correctly
- expect(findLabel('Artifacts').exists()).toBe(true);
- expect(findSectionLabel('Parameters').exists()).toBe(true);
- expect(findSectionLabel('Metadata').exists()).toBe(true);
- expect(findSectionLabel('Metrics').exists()).toBe(true);
- expect(findSectionLabel('CI').exists()).toBe(true);
- expect(findLabel('Merge request').exists()).toBe(true);
- expect(findLabel('Triggered by').exists()).toBe(true);
- });
});
describe('No artifact path', () => {
@@ -150,19 +168,19 @@ describe('MlCandidatesShow', () => {
);
it('does not render params', () => {
- expect(findSectionLabel('Parameters').exists()).toBe(false);
+ expect(findNoDataMessage(NO_PARAMETERS_MESSAGE).exists()).toBe(true);
});
it('does not render metadata', () => {
- expect(findSectionLabel('Metadata').exists()).toBe(false);
+ expect(findNoDataMessage(NO_METADATA_MESSAGE).exists()).toBe(true);
});
it('does not render metrics', () => {
- expect(findSectionLabel('Metrics').exists()).toBe(false);
+ expect(findNoDataMessage(NO_METRICS_MESSAGE).exists()).toBe(true);
});
it('does not render CI info', () => {
- expect(findSectionLabel('CI').exists()).toBe(false);
+ expect(findNoDataMessage(NO_CI_MESSAGE).exists()).toBe(true);
});
});
diff --git a/spec/frontend/ml/experiment_tracking/routes/candidates/show/mock_data.js b/spec/frontend/ml/experiment_tracking/routes/candidates/show/mock_data.js
index 3fbcf122997..4ea23ed2513 100644
--- a/spec/frontend/ml/experiment_tracking/routes/candidates/show/mock_data.js
+++ b/spec/frontend/ml/experiment_tracking/routes/candidates/show/mock_data.js
@@ -4,8 +4,11 @@ export const newCandidate = () => ({
{ name: 'MaxDepth', value: '3' },
],
metrics: [
- { name: 'AUC', value: '.55' },
- { name: 'Accuracy', value: '.99' },
+ { name: 'AUC', value: '.55', step: 0 },
+ { name: 'Accuracy', value: '.99', step: 1 },
+ { name: 'Accuracy', value: '.98', step: 2 },
+ { name: 'Accuracy', value: '.97', step: 3 },
+ { name: 'F1', value: '.1', step: 3 },
],
metadata: [
{ name: 'FileName', value: 'test.py' },