Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
9b577500
Commit
9b577500
authored
Jan 21, 2021
by
Frédéric Caplette
Committed by
Sarah Groff Hennigh-Palermo
Jan 21, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add tests for links inner component
This add tests for the link drawing in the CI config graph.
parent
58432c3f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
346 additions
and
13 deletions
+346
-13
app/assets/javascripts/pipelines/components/graph_shared/drawing_utils.js
...cripts/pipelines/components/graph_shared/drawing_utils.js
+2
-2
spec/frontend/pipelines/graph_shared/__snapshots__/links_inner_spec.js.snap
...lines/graph_shared/__snapshots__/links_inner_spec.js.snap
+23
-0
spec/frontend/pipelines/graph_shared/links_inner_spec.js
spec/frontend/pipelines/graph_shared/links_inner_spec.js
+197
-0
spec/frontend/pipelines/graph_shared/links_layer_spec.js
spec/frontend/pipelines/graph_shared/links_layer_spec.js
+0
-0
spec/frontend/pipelines/pipeline_graph/mock_data.js
spec/frontend/pipelines/pipeline_graph/mock_data.js
+124
-11
No files found.
app/assets/javascripts/pipelines/components/graph_shared/drawing_utils.js
View file @
9b577500
...
...
@@ -40,10 +40,10 @@ export const generateLinksData = ({ links }, containerID, modifier = '') => {
// positioned in the center of the job node by adding half the height
// of the job pill.
const
paddingLeft
=
parseFloat
(
window
.
getComputedStyle
(
containerEl
,
null
).
getPropertyValue
(
'
padding-left
'
),
window
.
getComputedStyle
(
containerEl
,
null
).
getPropertyValue
(
'
padding-left
'
)
||
0
,
);
const
paddingTop
=
parseFloat
(
window
.
getComputedStyle
(
containerEl
,
null
).
getPropertyValue
(
'
padding-top
'
),
window
.
getComputedStyle
(
containerEl
,
null
).
getPropertyValue
(
'
padding-top
'
)
||
0
,
);
const
sourceNodeX
=
sourceNodeCoordinates
.
right
-
containerCoordinates
.
x
-
paddingLeft
;
...
...
spec/frontend/pipelines/graph_shared/__snapshots__/links_inner_spec.js.snap
0 → 100644
View file @
9b577500
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Links Inner component with a large number of needs matches snapshot and has expected path 1`] = `
"<div class=\\"gl-display-flex gl-relative\\"><svg id=\\"link-svg\\" viewBox=\\"0,0,1019,445\\" width=\\"1019px\\" height=\\"445px\\" class=\\"gl-absolute\\">
<path d=\\"M202,118L42,118C72,118,72,138,102,138\\" stroke-width=\\"2\\" class=\\"gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease gl-stroke-gray-200\\"></path>
<path d=\\"M202,118L52,118C82,118,82,148,112,148\\" stroke-width=\\"2\\" class=\\"gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease gl-stroke-gray-200\\"></path>
<path d=\\"M222,138L62,138C92,138,92,158,122,158\\" stroke-width=\\"2\\" class=\\"gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease gl-stroke-gray-200\\"></path>
<path d=\\"M212,128L72,128C102,128,102,168,132,168\\" stroke-width=\\"2\\" class=\\"gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease gl-stroke-gray-200\\"></path>
<path d=\\"M232,148L82,148C112,148,112,178,142,178\\" stroke-width=\\"2\\" class=\\"gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease gl-stroke-gray-200\\"></path>
</svg> </div>"
`;
exports[`Links Inner component with a parallel need matches snapshot and has expected path 1`] = `
"<div class=\\"gl-display-flex gl-relative\\"><svg id=\\"link-svg\\" viewBox=\\"0,0,1019,445\\" width=\\"1019px\\" height=\\"445px\\" class=\\"gl-absolute\\">
<path d=\\"M192,108L22,108C52,108,52,118,82,118\\" stroke-width=\\"2\\" class=\\"gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease gl-stroke-gray-200\\"></path>
</svg> </div>"
`;
exports[`Links Inner component with one need matches snapshot and has expected path 1`] = `
"<div class=\\"gl-display-flex gl-relative\\"><svg id=\\"link-svg\\" viewBox=\\"0,0,1019,445\\" width=\\"1019px\\" height=\\"445px\\" class=\\"gl-absolute\\">
<path d=\\"M202,118L42,118C72,118,72,138,102,138\\" stroke-width=\\"2\\" class=\\"gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease gl-stroke-gray-200\\"></path>
</svg> </div>"
`;
spec/frontend/pipelines/graph_shared/links_inner_spec.js
0 → 100644
View file @
9b577500
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
setHTMLFixture
}
from
'
helpers/fixtures
'
;
import
LinksInner
from
'
~/pipelines/components/graph_shared/links_inner.vue
'
;
import
{
createJobsHash
}
from
'
~/pipelines/utils
'
;
import
{
jobRect
,
largePipelineData
,
parallelNeedData
,
pipelineData
,
pipelineDataWithNoNeeds
,
rootRect
,
}
from
'
../pipeline_graph/mock_data
'
;
describe
(
'
Links Inner component
'
,
()
=>
{
const
containerId
=
'
pipeline-graph-container
'
;
const
defaultProps
=
{
containerId
,
containerMeasurements
:
{
width
:
1019
,
height
:
445
},
pipelineId
:
1
,
pipelineData
:
[],
};
let
wrapper
;
const
createComponent
=
(
props
)
=>
{
wrapper
=
shallowMount
(
LinksInner
,
{
propsData
:
{
...
defaultProps
,
...
props
},
});
};
const
findLinkSvg
=
()
=>
wrapper
.
find
(
'
#link-svg
'
);
const
findAllLinksPath
=
()
=>
findLinkSvg
().
findAll
(
'
path
'
);
// We create fixture so that each job has an empty div that represent
// the JobPill in the DOM. Each `JobPill` would have different coordinates,
// so we increment their coordinates on each iteration to simulat different positions.
const
setFixtures
=
({
stages
})
=>
{
const
jobs
=
createJobsHash
(
stages
);
const
arrayOfJobs
=
Object
.
keys
(
jobs
);
const
linksHtmlElements
=
arrayOfJobs
.
map
((
job
)
=>
{
return
`<div id=
${
job
}
-
${
defaultProps
.
pipelineId
}
/>`
;
});
setHTMLFixture
(
`<div id="
${
containerId
}
">
${
linksHtmlElements
.
join
(
'
'
)}
</div>`
);
// We are mocking the clientRect data of each job and the container ID.
jest
.
spyOn
(
document
.
getElementById
(
containerId
),
'
getBoundingClientRect
'
)
.
mockImplementation
(()
=>
rootRect
);
arrayOfJobs
.
forEach
((
job
,
index
)
=>
{
jest
.
spyOn
(
document
.
getElementById
(
`
${
job
}
-
${
defaultProps
.
pipelineId
}
`
),
'
getBoundingClientRect
'
,
)
.
mockImplementation
(()
=>
{
const
newValue
=
10
*
index
;
const
{
left
,
right
,
top
,
bottom
,
x
,
y
}
=
jobRect
;
return
{
...
jobRect
,
left
:
left
+
newValue
,
right
:
right
+
newValue
,
top
:
top
+
newValue
,
bottom
:
bottom
+
newValue
,
x
:
x
+
newValue
,
y
:
y
+
newValue
,
};
});
});
};
afterEach
(()
=>
{
jest
.
restoreAllMocks
();
wrapper
.
destroy
();
wrapper
=
null
;
});
describe
(
'
basic SVG creation
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
();
});
it
(
'
renders an SVG of the right size
'
,
()
=>
{
expect
(
findLinkSvg
().
exists
()).
toBe
(
true
);
expect
(
findLinkSvg
().
attributes
(
'
width
'
)).
toBe
(
`
${
defaultProps
.
containerMeasurements
.
width
}
px`
,
);
expect
(
findLinkSvg
().
attributes
(
'
height
'
)).
toBe
(
`
${
defaultProps
.
containerMeasurements
.
height
}
px`
,
);
});
});
describe
(
'
no pipeline data
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
();
});
it
(
'
renders the component
'
,
()
=>
{
expect
(
findLinkSvg
().
exists
()).
toBe
(
true
);
expect
(
findAllLinksPath
()).
toHaveLength
(
0
);
});
});
describe
(
'
pipeline data with no needs
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
pipelineData
:
pipelineDataWithNoNeeds
.
stages
});
});
it
(
'
renders no links
'
,
()
=>
{
expect
(
findLinkSvg
().
exists
()).
toBe
(
true
);
expect
(
findAllLinksPath
()).
toHaveLength
(
0
);
});
});
describe
(
'
with one need
'
,
()
=>
{
beforeEach
(()
=>
{
setFixtures
(
pipelineData
);
createComponent
({
pipelineData
:
pipelineData
.
stages
});
});
it
(
'
renders one link
'
,
()
=>
{
expect
(
findAllLinksPath
()).
toHaveLength
(
1
);
});
it
(
'
path does not contain NaN values
'
,
()
=>
{
expect
(
wrapper
.
html
()).
not
.
toContain
(
'
NaN
'
);
});
it
(
'
matches snapshot and has expected path
'
,
()
=>
{
expect
(
wrapper
.
html
()).
toMatchSnapshot
();
});
});
describe
(
'
with a parallel need
'
,
()
=>
{
beforeEach
(()
=>
{
setFixtures
(
parallelNeedData
);
createComponent
({
pipelineData
:
parallelNeedData
.
stages
});
});
it
(
'
renders only one link for all the same parallel jobs
'
,
()
=>
{
expect
(
findAllLinksPath
()).
toHaveLength
(
1
);
});
it
(
'
path does not contain NaN values
'
,
()
=>
{
expect
(
wrapper
.
html
()).
not
.
toContain
(
'
NaN
'
);
});
it
(
'
matches snapshot and has expected path
'
,
()
=>
{
expect
(
wrapper
.
html
()).
toMatchSnapshot
();
});
});
describe
(
'
with a large number of needs
'
,
()
=>
{
beforeEach
(()
=>
{
setFixtures
(
largePipelineData
);
createComponent
({
pipelineData
:
largePipelineData
.
stages
});
});
it
(
'
renders the correct number of links
'
,
()
=>
{
expect
(
findAllLinksPath
()).
toHaveLength
(
5
);
});
it
(
'
path does not contain NaN values
'
,
()
=>
{
expect
(
wrapper
.
html
()).
not
.
toContain
(
'
NaN
'
);
});
it
(
'
matches snapshot and has expected path
'
,
()
=>
{
expect
(
wrapper
.
html
()).
toMatchSnapshot
();
});
});
describe
(
'
interactions
'
,
()
=>
{
beforeEach
(()
=>
{
setFixtures
(
largePipelineData
);
createComponent
({
pipelineData
:
largePipelineData
.
stages
});
});
it
(
'
highlight needs on hover
'
,
async
()
=>
{
const
firstLink
=
findAllLinksPath
().
at
(
0
);
const
defaultColorClass
=
'
gl-stroke-gray-200
'
;
const
hoverColorClass
=
'
gl-stroke-blue-400
'
;
expect
(
firstLink
.
classes
(
defaultColorClass
)).
toBe
(
true
);
expect
(
firstLink
.
classes
(
hoverColorClass
)).
toBe
(
false
);
// Because there is a watcher, we need to set the props after the component
// has mounted.
await
wrapper
.
setProps
({
highlightedJob
:
'
test_1
'
});
expect
(
firstLink
.
classes
(
defaultColorClass
)).
toBe
(
false
);
expect
(
firstLink
.
classes
(
hoverColorClass
)).
toBe
(
true
);
});
});
});
spec/frontend/pipelines/shared/links_layer_spec.js
→
spec/frontend/pipelines/
graph_
shared/links_layer_spec.js
View file @
9b577500
File moved
spec/frontend/pipelines/pipeline_graph/mock_data.js
View file @
9b577500
import
{
createUniqueLinkId
}
from
'
~/pipelines/components/graph_shared/drawing_utils
'
;
export
const
yamlString
=
`stages:
- empty
- build
...
...
@@ -41,10 +39,28 @@ deploy_a:
script: echo hello
`
;
const
jobId1
=
createUniqueLinkId
(
'
build
'
,
'
build_1
'
);
const
jobId2
=
createUniqueLinkId
(
'
test
'
,
'
test_1
'
);
const
jobId3
=
createUniqueLinkId
(
'
test
'
,
'
test_2
'
);
const
jobId4
=
createUniqueLinkId
(
'
deploy
'
,
'
deploy_1
'
);
export
const
pipelineDataWithNoNeeds
=
{
stages
:
[
{
name
:
'
build
'
,
groups
:
[
{
name
:
'
build_1
'
,
jobs
:
[{
script
:
'
echo hello
'
,
stage
:
'
build
'
}],
},
],
},
{
name
:
'
test
'
,
groups
:
[
{
name
:
'
test_1
'
,
jobs
:
[{
script
:
'
yarn test
'
,
stage
:
'
test
'
}],
},
],
},
],
};
export
const
pipelineData
=
{
stages
:
[
...
...
@@ -54,7 +70,6 @@ export const pipelineData = {
{
name
:
'
build_1
'
,
jobs
:
[{
script
:
'
echo hello
'
,
stage
:
'
build
'
}],
id
:
jobId1
,
},
],
},
...
...
@@ -64,12 +79,10 @@ export const pipelineData = {
{
name
:
'
test_1
'
,
jobs
:
[{
script
:
'
yarn test
'
,
stage
:
'
test
'
}],
id
:
jobId2
,
},
{
name
:
'
test_2
'
,
jobs
:
[{
script
:
'
yarn karma
'
,
stage
:
'
test
'
}],
id
:
jobId3
,
},
],
},
...
...
@@ -79,7 +92,86 @@ export const pipelineData = {
{
name
:
'
deploy_1
'
,
jobs
:
[{
script
:
'
yarn magick
'
,
stage
:
'
deploy
'
,
needs
:
[
'
test_1
'
]
}],
id
:
jobId4
,
},
],
},
],
};
export
const
parallelNeedData
=
{
stages
:
[
{
name
:
'
build
'
,
groups
:
[
{
name
:
'
build_1
'
,
parallel
:
3
,
jobs
:
[
{
script
:
'
echo hello
'
,
stage
:
'
build
'
,
name
:
'
build_1 1/3
'
},
{
script
:
'
echo hello
'
,
stage
:
'
build
'
,
name
:
'
build_1 2/3
'
},
{
script
:
'
echo hello
'
,
stage
:
'
build
'
,
name
:
'
build_1 3/3
'
},
],
},
],
},
{
name
:
'
test
'
,
groups
:
[
{
name
:
'
test_1
'
,
jobs
:
[{
script
:
'
yarn test
'
,
stage
:
'
test
'
,
needs
:
[
'
build_1
'
]
}],
},
],
},
],
};
export
const
largePipelineData
=
{
stages
:
[
{
name
:
'
build
'
,
groups
:
[
{
name
:
'
build_1
'
,
jobs
:
[{
script
:
'
echo hello
'
,
stage
:
'
build
'
}],
},
{
name
:
'
build_2
'
,
jobs
:
[{
script
:
'
echo hello
'
,
stage
:
'
build
'
}],
},
{
name
:
'
build_3
'
,
jobs
:
[{
script
:
'
echo hello
'
,
stage
:
'
build
'
}],
},
],
},
{
name
:
'
test
'
,
groups
:
[
{
name
:
'
test_1
'
,
jobs
:
[{
script
:
'
yarn test
'
,
stage
:
'
test
'
,
needs
:
[
'
build_2
'
]
}],
},
{
name
:
'
test_2
'
,
jobs
:
[{
script
:
'
yarn karma
'
,
stage
:
'
test
'
,
needs
:
[
'
build_2
'
]
}],
},
],
},
{
name
:
'
deploy
'
,
groups
:
[
{
name
:
'
deploy_1
'
,
jobs
:
[{
script
:
'
yarn magick
'
,
stage
:
'
deploy
'
,
needs
:
[
'
test_1
'
]
}],
},
{
name
:
'
deploy_2
'
,
jobs
:
[{
script
:
'
yarn magick
'
,
stage
:
'
deploy
'
,
needs
:
[
'
build_3
'
]
}],
},
{
name
:
'
deploy_3
'
,
jobs
:
[{
script
:
'
yarn magick
'
,
stage
:
'
deploy
'
,
needs
:
[
'
test_2
'
]
}],
},
],
},
...
...
@@ -94,9 +186,30 @@ export const singleStageData = {
{
name
:
'
build_1
'
,
jobs
:
[{
script
:
'
echo hello
'
,
stage
:
'
build
'
}],
id
:
jobId1
,
},
],
},
],
};
export
const
rootRect
=
{
bottom
:
463
,
height
:
271
,
left
:
236
,
right
:
1252
,
top
:
192
,
width
:
1016
,
x
:
236
,
y
:
192
,
};
export
const
jobRect
=
{
bottom
:
312
,
height
:
24
,
left
:
308
,
right
:
428
,
top
:
288
,
width
:
120
,
x
:
308
,
y
:
288
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment