Commit 1dc051fb authored by Mike Greiling's avatar Mike Greiling Committed by Tim Zallmann

Resolve "Add graph value to hover"

parent 78b044a1
...@@ -69,8 +69,8 @@ ...@@ -69,8 +69,8 @@
currentFlagPosition: 0, currentFlagPosition: 0,
showFlag: false, showFlag: false,
showFlagContent: false, showFlagContent: false,
showDeployInfo: true,
timeSeries: [], timeSeries: [],
realPixelRatio: 1,
}; };
}, },
...@@ -87,10 +87,7 @@ ...@@ -87,10 +87,7 @@
}, },
innerViewBox() { innerViewBox() {
if ((this.baseGraphWidth - 150) > 0) { return `0 0 ${this.baseGraphWidth - 150} ${this.baseGraphHeight}`;
return `0 0 ${this.baseGraphWidth - 150} ${this.baseGraphHeight}`;
}
return '0 0 0 0';
}, },
axisTransform() { axisTransform() {
...@@ -102,6 +99,10 @@ ...@@ -102,6 +99,10 @@
paddingBottom: `${(Math.ceil(this.baseGraphHeight * 100) / this.baseGraphWidth) || 0}%`, paddingBottom: `${(Math.ceil(this.baseGraphHeight * 100) / this.baseGraphWidth) || 0}%`,
}; };
}, },
deploymentFlagData() {
return this.reducedDeploymentData.find(deployment => deployment.showDeploymentFlag);
},
}, },
methods: { methods: {
...@@ -122,6 +123,10 @@ ...@@ -122,6 +123,10 @@
this.graphHeight = this.graphHeight - this.margin.top - this.margin.bottom; this.graphHeight = this.graphHeight - this.margin.top - this.margin.bottom;
this.baseGraphHeight = this.graphHeight; this.baseGraphHeight = this.graphHeight;
this.baseGraphWidth = this.graphWidth; this.baseGraphWidth = this.graphWidth;
// pixel offsets inside the svg and outside are not 1:1
this.realPixelRatio = (this.$refs.baseSvg.clientWidth / this.baseGraphWidth);
this.renderAxesPaths(); this.renderAxesPaths();
this.formatDeployments(); this.formatDeployments();
}, },
...@@ -261,6 +266,11 @@ ...@@ -261,6 +266,11 @@
:line-color="path.lineColor" :line-color="path.lineColor"
:area-color="path.areaColor" :area-color="path.areaColor"
/> />
<graph-deployment
:deployment-data="reducedDeploymentData"
:graph-height="graphHeight"
:graph-height-offset="graphHeightOffset"
/>
<rect <rect
class="prometheus-graph-overlay" class="prometheus-graph-overlay"
:width="(graphWidth - 70)" :width="(graphWidth - 70)"
...@@ -269,24 +279,21 @@ ...@@ -269,24 +279,21 @@
ref="graphOverlay" ref="graphOverlay"
@mousemove="handleMouseOverGraph($event)"> @mousemove="handleMouseOverGraph($event)">
</rect> </rect>
<graph-deployment
:show-deploy-info="showDeployInfo"
:deployment-data="reducedDeploymentData"
:graph-width="graphWidth"
:graph-height="graphHeight"
:graph-height-offset="graphHeightOffset"
/>
<graph-flag
v-if="showFlag"
:current-x-coordinate="currentXCoordinate"
:current-data="currentData"
:current-flag-position="currentFlagPosition"
:graph-height="graphHeight"
:graph-height-offset="graphHeightOffset"
:show-flag-content="showFlagContent"
/>
</svg> </svg>
</svg> </svg>
<graph-flag
:real-pixel-ratio="realPixelRatio"
:current-x-coordinate="currentXCoordinate"
:current-data="currentData"
:graph-height="graphHeight"
:graph-height-offset="graphHeightOffset"
:show-flag-content="showFlagContent"
:time-series="timeSeries"
:unit-of-display="unitOfDisplay"
:current-data-index="currentDataIndex"
:legend-title="legendTitle"
:deployment-flag-data="deploymentFlagData"
/>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { dateFormatWithName, timeFormat } from '../../utils/date_time_formatters';
import Icon from '../../../vue_shared/components/icon.vue';
export default { export default {
props: { props: {
showDeployInfo: {
type: Boolean,
required: true,
},
deploymentData: { deploymentData: {
type: Array, type: Array,
required: true, required: true,
...@@ -20,14 +13,6 @@ ...@@ -20,14 +13,6 @@
type: Number, type: Number,
required: true, required: true,
}, },
graphWidth: {
type: Number,
required: true,
},
},
components: {
Icon,
}, },
computed: { computed: {
...@@ -37,52 +22,17 @@ ...@@ -37,52 +22,17 @@
}, },
methods: { methods: {
refText(d) {
return d.tag ? d.ref : d.sha.slice(0, 8);
},
formatTime(deploymentTime) {
return timeFormat(deploymentTime);
},
formatDate(deploymentTime) {
return dateFormatWithName(deploymentTime);
},
nameDeploymentClass(deployment) {
return `deploy-info-${deployment.id}`;
},
transformDeploymentGroup(deployment) { transformDeploymentGroup(deployment) {
return `translate(${Math.floor(deployment.xPos) + 1}, 20)`; return `translate(${Math.floor(deployment.xPos) - 5}, 20)`;
},
positionFlag(deployment) {
let xPosition = 3;
if (deployment.xPos > (this.graphWidth - 225)) {
xPosition = -142;
}
return xPosition;
},
svgContainerHeight(tag) {
let svgHeight = 80;
if (!tag) {
svgHeight -= 20;
}
return svgHeight;
}, },
}, },
}; };
</script> </script>
<template> <template>
<g <g class="deploy-info">
class="deploy-info"
v-if="showDeployInfo">
<g <g
v-for="(deployment, index) in deploymentData" v-for="(deployment, index) in deploymentData"
:key="index" :key="index"
:class="nameDeploymentClass(deployment)"
:transform="transformDeploymentGroup(deployment)"> :transform="transformDeploymentGroup(deployment)">
<rect <rect
x="0" x="0"
...@@ -99,81 +49,6 @@ ...@@ -99,81 +49,6 @@
:y2="calculatedHeight" :y2="calculatedHeight"
stroke="#000"> stroke="#000">
</line> </line>
<svg
v-if="deployment.showDeploymentFlag"
class="js-deploy-info-box"
:x="positionFlag(deployment)"
y="0"
width="134"
:height="svgContainerHeight(deployment.tag)">
<rect
class="rect-text-metric deploy-info-rect rect-metric"
x="1"
y="1"
rx="2"
width="132"
:height="svgContainerHeight(deployment.tag) - 2">
</rect>
<text
class="deploy-info-text text-metric-bold"
transform="translate(5, 2)">
Deployed
</text>
<!--The date info-->
<g transform="translate(5, 20)">
<text class="deploy-info-text">
{{formatDate(deployment.time)}}
</text>
<text
class="deploy-info-text text-metric-bold"
x="62">
{{formatTime(deployment.time)}}
</text>
</g>
<line
class="divider-line"
x1="0"
y1="38"
x2="132"
:y2="38"
stroke="#000">
</line>
<!--Commit information-->
<g transform="translate(5, 40)">
<icon
name="commit"
:width="12"
:height="12"
:y="3">
</icon>
<a :xlink:href="deployment.commitUrl">
<text
class="deploy-info-text deploy-info-text-link"
transform="translate(20, 2)">
{{refText(deployment)}}
</text>
</a>
</g>
<!--Tag information-->
<g
transform="translate(5, 55)"
v-if="deployment.tag">
<icon
name="label"
:width="12"
:height="12"
:y="5">
</icon>
<a :xlink:href="deployment.tagUrl">
<text
class="deploy-info-text deploy-info-text-link"
transform="translate(20, 2)"
y="2">
{{deployment.tag}}
</text>
</a>
</g>
</svg>
</g> </g>
<svg <svg
height="0" height="0"
......
<script> <script>
import { dateFormat, timeFormat } from '../../utils/date_time_formatters'; import { dateFormat, timeFormat } from '../../utils/date_time_formatters';
import { formatRelevantDigits } from '../../../lib/utils/number_utils';
import Icon from '../../../vue_shared/components/icon.vue';
export default { export default {
props: { props: {
...@@ -7,14 +9,15 @@ ...@@ -7,14 +9,15 @@
type: Number, type: Number,
required: true, required: true,
}, },
currentFlagPosition: {
type: Number,
required: true,
},
currentData: { currentData: {
type: Object, type: Object,
required: true, required: true,
}, },
deploymentFlagData: {
type: Object,
required: false,
default: null,
},
graphHeight: { graphHeight: {
type: Number, type: Number,
required: true, required: true,
...@@ -23,71 +26,173 @@ ...@@ -23,71 +26,173 @@
type: Number, type: Number,
required: true, required: true,
}, },
realPixelRatio: {
type: Number,
required: true,
},
showFlagContent: { showFlagContent: {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
timeSeries: {
type: Array,
required: true,
},
unitOfDisplay: {
type: String,
required: true,
},
currentDataIndex: {
type: Number,
required: true,
},
legendTitle: {
type: String,
required: true,
},
}, },
data() { components: {
return { Icon,
circleColorRgb: '#8fbce8',
};
}, },
computed: { computed: {
formatTime() { formatTime() {
return timeFormat(this.currentData.time); return this.deploymentFlagData ?
timeFormat(this.deploymentFlagData.time) :
timeFormat(this.currentData.time);
}, },
formatDate() { formatDate() {
return dateFormat(this.currentData.time); return this.deploymentFlagData ?
dateFormat(this.deploymentFlagData.time) :
dateFormat(this.currentData.time);
},
cursorStyle() {
const xCoordinate = this.deploymentFlagData ?
this.deploymentFlagData.xPos :
this.currentXCoordinate;
const offsetTop = 20 * this.realPixelRatio;
const offsetLeft = (70 + xCoordinate) * this.realPixelRatio;
const height = (this.graphHeight - this.graphHeightOffset) * this.realPixelRatio;
return {
top: `${offsetTop}px`,
left: `${offsetLeft}px`,
height: `${height}px`,
};
},
flagOrientation() {
if (this.currentXCoordinate * this.realPixelRatio > 120) {
return 'left';
}
return 'right';
},
},
methods: {
seriesMetricValue(series) {
const index = this.deploymentFlagData ?
this.deploymentFlagData.seriesIndex :
this.currentDataIndex;
const value = series.values[index] &&
series.values[index].value;
if (isNaN(value)) {
return '-';
}
return `${formatRelevantDigits(value)}${this.unitOfDisplay}`;
}, },
calculatedHeight() { seriesMetricLabel(index, series) {
return this.graphHeight - this.graphHeightOffset; if (this.timeSeries.length < 2) {
return this.legendTitle;
}
if (series.metricTag) {
return series.metricTag;
}
return `series ${index + 1}`;
},
strokeDashArray(type) {
if (type === 'dashed') return '6, 3';
if (type === 'dotted') return '3, 3';
return null;
}, },
}, },
}; };
</script> </script>
<template> <template>
<g class="mouse-over-flag"> <div
<line class="prometheus-graph-cursor"
class="selected-metric-line" :style="cursorStyle"
:x1="currentXCoordinate" >
:y1="0" <div
:x2="currentXCoordinate"
:y2="calculatedHeight"
transform="translate(-5, 20)">
</line>
<svg
v-if="showFlagContent" v-if="showFlagContent"
class="rect-text-metric" class="prometheus-graph-flag popover"
:x="currentFlagPosition" :class="flagOrientation"
y="0"> >
<rect <div class="arrow"></div>
class="rect-metric" <div class="popover-title">
x="4" <h5 v-if="this.deploymentFlagData">
y="1" Deployed
rx="2" </h5>
width="90" {{formatDate}} at
height="40" <strong>{{formatTime}}</strong>
transform="translate(-3, 20)"> </div>
</rect> <div
<text v-if="this.deploymentFlagData"
class="text-metric text-metric-bold" class="popover-content deploy-meta-content"
x="16" >
y="35" <div>
transform="translate(-5, 20)"> <icon
{{formatTime}} name="commit"
</text> :size="12">
<text </icon>
class="text-metric" <a :href="deploymentFlagData.commitUrl">
x="16" {{deploymentFlagData.sha.slice(0, 8)}}
y="15" </a>
transform="translate(-5, 20)"> </div>
{{formatDate}} <div
</text> v-if="deploymentFlagData.tag">
</svg> <icon
</g> name="label"
:size="12">
</icon>
<a :href="deploymentFlagData.tagUrl">
{{deploymentFlagData.ref}}
</a>
</div>
</div>
<div class="popover-content">
<table>
<tr
v-for="(series, index) in timeSeries"
:key="index"
>
<td>
<svg width="15" height="6">
<line
:stroke="series.lineColor"
:stroke-dasharray="strokeDashArray(series.lineStyle)"
stroke-width="4"
x1="0"
x2="15"
y1="2"
y2="2">
</line>
</svg>
</td>
<td>{{seriesMetricLabel(index, series)}}</td>
<td>
<strong>{{seriesMetricValue(series)}}</strong>
</td>
</tr>
</table>
</div>
</div>
</div>
</template> </template>
...@@ -29,15 +29,18 @@ const mixins = { ...@@ -29,15 +29,18 @@ const mixins = {
time.setSeconds(this.timeSeries[0].values[0].time.getSeconds()); time.setSeconds(this.timeSeries[0].values[0].time.getSeconds());
if (xPos >= 0) { if (xPos >= 0) {
const seriesIndex = bisectDate(this.timeSeries[0].values, time, 1);
deploymentDataArray.push({ deploymentDataArray.push({
id: deployment.id, id: deployment.id,
time, time,
sha: deployment.sha, sha: deployment.sha,
commitUrl: `${this.projectPath}/commit/${deployment.sha}`, commitUrl: `${this.projectPath}/commit/${deployment.sha}`,
tag: deployment.tag, tag: deployment.tag,
tagUrl: `${this.tagsPath}/${deployment.tag}`, tagUrl: deployment.tag ? `${this.tagsPath}/${deployment.ref.name}` : null,
ref: deployment.ref.name, ref: deployment.ref.name,
xPos, xPos,
seriesIndex,
showDeploymentFlag: false, showDeploymentFlag: false,
}); });
} }
......
...@@ -14,7 +14,7 @@ const d3 = { ...@@ -14,7 +14,7 @@ const d3 = {
timeYear, timeYear,
}; };
export const dateFormat = d3.time('%b %-d, %Y'); export const dateFormat = d3.time('%a, %b %-d');
export const timeFormat = d3.time('%-I:%M%p'); export const timeFormat = d3.time('%-I:%M%p');
export const dateFormatWithName = d3.time('%a, %b %-d'); export const dateFormatWithName = d3.time('%a, %b %-d');
export const bisectDate = d3.bisector(d => d.time).left; export const bisectDate = d3.bisector(d => d.time).left;
......
...@@ -248,6 +248,73 @@ ...@@ -248,6 +248,73 @@
} }
} }
.prometheus-graph-cursor {
position: absolute;
background: $theme-gray-600;
width: 1px;
}
.prometheus-graph-flag {
display: block;
min-width: 160px;
h5 {
padding: 0;
margin: 0;
font-size: 14px;
line-height: 1.2;
}
table {
border-collapse: collapse;
padding: 0;
margin: 0;
}
td {
vertical-align: middle;
+ td {
padding-left: 5px;
vertical-align: top;
}
}
.deploy-meta-content {
border-bottom: 1px solid $white-dark;
svg {
height: 15px;
vertical-align: bottom;
}
}
&.popover {
&.left {
left: auto;
right: 0;
margin-right: 10px;
}
&.right {
left: 0;
right: auto;
margin-left: 10px;
}
> .arrow {
top: 40px;
}
> .popover-title,
> .popover-content {
padding: 5px 8px;
font-size: 12px;
white-space: nowrap;
}
}
}
.prometheus-svg-container { .prometheus-svg-container {
position: relative; position: relative;
height: 0; height: 0;
......
---
title: Display graph values on hover within monitoring page
merge_request: 16261
author:
type: changed
...@@ -11,168 +11,38 @@ const createComponent = (propsData) => { ...@@ -11,168 +11,38 @@ const createComponent = (propsData) => {
}; };
describe('MonitoringDeployment', () => { describe('MonitoringDeployment', () => {
const reducedDeploymentData = [deploymentData[0]];
reducedDeploymentData[0].ref = reducedDeploymentData[0].ref.name;
reducedDeploymentData[0].xPos = 10;
reducedDeploymentData[0].time = new Date(reducedDeploymentData[0].created_at);
describe('Methods', () => { describe('Methods', () => {
it('refText shows the ref when a tag is available', () => { it('should contain a hidden gradient', () => {
reducedDeploymentData[0].tag = '1.0';
const component = createComponent({
showDeployInfo: false,
deploymentData: reducedDeploymentData,
graphWidth: 440,
graphHeight: 300,
graphHeightOffset: 120,
});
expect(
component.refText(reducedDeploymentData[0]),
).toEqual(reducedDeploymentData[0].ref);
});
it('refText shows the sha when no tag is available', () => {
reducedDeploymentData[0].tag = null;
const component = createComponent({
showDeployInfo: false,
deploymentData: reducedDeploymentData,
graphHeight: 300,
graphWidth: 440,
graphHeightOffset: 120,
});
expect(
component.refText(reducedDeploymentData[0]),
).toContain('f5bcd1');
});
it('nameDeploymentClass creates a class with the prefix deploy-info-', () => {
const component = createComponent({ const component = createComponent({
showDeployInfo: false, showDeployInfo: true,
deploymentData: reducedDeploymentData, deploymentData,
graphHeight: 300, graphHeight: 300,
graphWidth: 440, graphWidth: 440,
graphHeightOffset: 120, graphHeightOffset: 120,
}); });
expect( expect(component.$el.querySelector('#shadow-gradient')).not.toBeNull();
component.nameDeploymentClass(reducedDeploymentData[0]),
).toContain('deploy-info');
}); });
it('transformDeploymentGroup translates an available deployment', () => { it('transformDeploymentGroup translates an available deployment', () => {
const component = createComponent({ const component = createComponent({
showDeployInfo: false, showDeployInfo: false,
deploymentData: reducedDeploymentData, deploymentData,
graphHeight: 300, graphHeight: 300,
graphWidth: 440, graphWidth: 440,
graphHeightOffset: 120, graphHeightOffset: 120,
}); });
expect( expect(
component.transformDeploymentGroup(reducedDeploymentData[0]), component.transformDeploymentGroup({ xPos: 16 }),
).toContain('translate(11, 20)'); ).toContain('translate(11, 20)');
}); });
it('hides the deployment flag', () => {
reducedDeploymentData[0].showDeploymentFlag = false;
const component = createComponent({
showDeployInfo: true,
deploymentData: reducedDeploymentData,
graphWidth: 440,
graphHeight: 300,
graphHeightOffset: 120,
});
expect(component.$el.querySelector('.js-deploy-info-box')).toBeNull();
});
it('positions the flag to the left when the xPos is too far right', () => {
reducedDeploymentData[0].showDeploymentFlag = false;
reducedDeploymentData[0].xPos = 250;
const component = createComponent({
showDeployInfo: true,
deploymentData: reducedDeploymentData,
graphWidth: 440,
graphHeight: 300,
graphHeightOffset: 120,
});
expect(
component.positionFlag(reducedDeploymentData[0]),
).toBeLessThan(0);
});
it('shows the deployment flag', () => {
reducedDeploymentData[0].showDeploymentFlag = true;
const component = createComponent({
showDeployInfo: true,
deploymentData: reducedDeploymentData,
graphHeight: 300,
graphWidth: 440,
graphHeightOffset: 120,
});
expect(
component.$el.querySelector('.js-deploy-info-box').style.display,
).not.toEqual('display: none;');
});
it('contains date, refs and the "deployed" text', () => {
reducedDeploymentData[0].showDeploymentFlag = true;
const component = createComponent({
showDeployInfo: true,
deploymentData: reducedDeploymentData,
graphHeight: 300,
graphWidth: 440,
graphHeightOffset: 120,
});
expect(
component.$el.querySelectorAll('.deploy-info-text'),
).toContainText('Deployed');
expect(
component.$el.querySelectorAll('.deploy-info-text'),
).toContainText('Wed, May 31');
expect(
component.$el.querySelectorAll('.deploy-info-text'),
).toContainText(component.refText(reducedDeploymentData[0]));
});
it('contains a link to the commit contents', () => {
reducedDeploymentData[0].showDeploymentFlag = true;
const component = createComponent({
showDeployInfo: true,
deploymentData: reducedDeploymentData,
graphHeight: 300,
graphWidth: 440,
graphHeightOffset: 120,
});
expect(
component.$el.querySelectorAll('.deploy-info-text-link')[0].parentElement.getAttribute('xlink:href'),
).not.toEqual('');
});
it('should contain a hidden gradient', () => {
const component = createComponent({
showDeployInfo: true,
deploymentData: reducedDeploymentData,
graphHeight: 300,
graphWidth: 440,
graphHeightOffset: 120,
});
expect(component.$el.querySelector('#shadow-gradient')).not.toBeNull();
});
describe('Computed props', () => { describe('Computed props', () => {
it('calculatedHeight', () => { it('calculatedHeight', () => {
const component = createComponent({ const component = createComponent({
showDeployInfo: true, showDeployInfo: true,
deploymentData: reducedDeploymentData, deploymentData,
graphHeight: 300, graphHeight: 300,
graphWidth: 440, graphWidth: 440,
graphHeightOffset: 120, graphHeightOffset: 120,
......
import Vue from 'vue'; import Vue from 'vue';
import GraphFlag from '~/monitoring/components/graph/flag.vue'; import GraphFlag from '~/monitoring/components/graph/flag.vue';
import { deploymentData } from '../mock_data';
const createComponent = (propsData) => { const createComponent = (propsData) => {
const Component = Vue.extend(GraphFlag); const Component = Vue.extend(GraphFlag);
...@@ -9,11 +10,6 @@ const createComponent = (propsData) => { ...@@ -9,11 +10,6 @@ const createComponent = (propsData) => {
}).$mount(); }).$mount();
}; };
function getCoordinate(component, selector, coordinate) {
const coordinateVal = component.$el.querySelector(selector).getAttribute(coordinate);
return parseInt(coordinateVal, 10);
}
const defaultValuesComponent = { const defaultValuesComponent = {
currentXCoordinate: 200, currentXCoordinate: 200,
currentYCoordinate: 100, currentYCoordinate: 100,
...@@ -25,31 +21,111 @@ const defaultValuesComponent = { ...@@ -25,31 +21,111 @@ const defaultValuesComponent = {
graphHeight: 300, graphHeight: 300,
graphHeightOffset: 120, graphHeightOffset: 120,
showFlagContent: true, showFlagContent: true,
realPixelRatio: 1,
timeSeries: [{
values: [{
time: new Date('2017-06-04T18:17:33.501Z'),
value: '1.49609375',
}],
}],
unitOfDisplay: 'ms',
currentDataIndex: 0,
legendTitle: 'Average',
};
const deploymentFlagData = {
...deploymentData[0],
ref: deploymentData[0].ref.name,
xPos: 10,
time: new Date(deploymentData[0].created_at),
}; };
describe('GraphFlag', () => { describe('GraphFlag', () => {
it('has a line and a circle located at the currentXCoordinate and currentYCoordinate', () => { let component;
const component = createComponent(defaultValuesComponent);
expect(getCoordinate(component, '.selected-metric-line', 'x1')) it('has a line at the currentXCoordinate', () => {
.toEqual(component.currentXCoordinate); component = createComponent(defaultValuesComponent);
expect(getCoordinate(component, '.selected-metric-line', 'x2'))
.toEqual(component.currentXCoordinate); expect(component.$el.style.left)
.toEqual(`${70 + component.currentXCoordinate}px`);
}); });
it('has a SVG with the class rect-text-metric at the currentFlagPosition', () => { describe('Deployment flag', () => {
const component = createComponent(defaultValuesComponent); it('shows a deployment flag when deployment data provided', () => {
const deploymentFlagComponent = createComponent({
...defaultValuesComponent,
deploymentFlagData,
});
expect(
deploymentFlagComponent.$el.querySelector('.popover-title'),
).toContainText('Deployed');
});
it('contains the ref when a tag is available', () => {
const deploymentFlagComponent = createComponent({
...defaultValuesComponent,
deploymentFlagData: {
...deploymentFlagData,
sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
tag: true,
ref: '1.0',
},
});
expect(
deploymentFlagComponent.$el.querySelector('.deploy-meta-content'),
).toContainText('f5bcd1d9');
expect(
deploymentFlagComponent.$el.querySelector('.deploy-meta-content'),
).toContainText('1.0');
});
it('does not contain the ref when a tag is unavailable', () => {
const deploymentFlagComponent = createComponent({
...defaultValuesComponent,
deploymentFlagData: {
...deploymentFlagData,
sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
tag: false,
ref: '1.0',
},
});
expect(
deploymentFlagComponent.$el.querySelector('.deploy-meta-content'),
).toContainText('f5bcd1d9');
const svg = component.$el.querySelector('.rect-text-metric'); expect(
expect(svg.tagName).toEqual('svg'); deploymentFlagComponent.$el.querySelector('.deploy-meta-content'),
expect(parseInt(svg.getAttribute('x'), 10)).toEqual(component.currentFlagPosition); ).not.toContainText('1.0');
});
}); });
describe('Computed props', () => { describe('Computed props', () => {
it('calculatedHeight', () => { beforeEach(() => {
const component = createComponent(defaultValuesComponent); component = createComponent(defaultValuesComponent);
});
it('formatTime', () => {
expect(component.formatTime).toMatch(/\d:17PM/);
});
it('formatDate', () => {
expect(component.formatDate).toEqual('Sun, Jun 4');
});
it('cursorStyle', () => {
expect(component.cursorStyle).toEqual({
top: '20px',
left: '270px',
height: '180px',
});
});
expect(component.calculatedHeight).toEqual(180); it('flagOrientation', () => {
expect(component.flagOrientation).toEqual('left');
}); });
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment