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
174c2f80
Commit
174c2f80
authored
Mar 16, 2018
by
Phil Hughes
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into ide-code-cleanup
parents
2a7fedaf
97c7c8ec
Changes
34
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
1040 additions
and
416 deletions
+1040
-416
app/assets/javascripts/merge_request_tabs.js
app/assets/javascripts/merge_request_tabs.js
+5
-0
app/assets/stylesheets/pages/repo.scss
app/assets/stylesheets/pages/repo.scss
+88
-2
doc/administration/geo/replication/configuration.md
doc/administration/geo/replication/configuration.md
+11
-7
doc/ci/examples/code_climate.md
doc/ci/examples/code_climate.md
+15
-7
doc/development/doc_styleguide.md
doc/development/doc_styleguide.md
+71
-266
doc/development/writing_documentation.md
doc/development/writing_documentation.md
+245
-30
ee/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
...s/javascripts/ide/components/commit_sidebar/list_item.vue
+3
-0
ee/app/assets/javascripts/ide/components/editor_mode_dropdown.vue
...ssets/javascripts/ide/components/editor_mode_dropdown.vue
+91
-0
ee/app/assets/javascripts/ide/components/ide.vue
ee/app/assets/javascripts/ide/components/ide.vue
+5
-8
ee/app/assets/javascripts/ide/components/repo_editor.vue
ee/app/assets/javascripts/ide/components/repo_editor.vue
+28
-3
ee/app/assets/javascripts/ide/components/repo_file.vue
ee/app/assets/javascripts/ide/components/repo_file.vue
+13
-5
ee/app/assets/javascripts/ide/components/repo_tabs.vue
ee/app/assets/javascripts/ide/components/repo_tabs.vue
+42
-8
ee/app/assets/javascripts/ide/lib/common/model.js
ee/app/assets/javascripts/ide/lib/common/model.js
+4
-0
ee/app/assets/javascripts/ide/lib/common/model_manager.js
ee/app/assets/javascripts/ide/lib/common/model_manager.js
+9
-0
ee/app/assets/javascripts/ide/lib/decorations/controller.js
ee/app/assets/javascripts/ide/lib/decorations/controller.js
+2
-0
ee/app/assets/javascripts/ide/lib/editor.js
ee/app/assets/javascripts/ide/lib/editor.js
+69
-25
ee/app/assets/javascripts/ide/lib/editor_options.js
ee/app/assets/javascripts/ide/lib/editor_options.js
+15
-3
ee/app/assets/javascripts/ide/lib/themes/gl_theme.js
ee/app/assets/javascripts/ide/lib/themes/gl_theme.js
+3
-0
ee/app/assets/javascripts/ide/stores/actions.js
ee/app/assets/javascripts/ide/stores/actions.js
+8
-0
ee/app/assets/javascripts/ide/stores/actions/file.js
ee/app/assets/javascripts/ide/stores/actions/file.js
+47
-15
ee/app/assets/javascripts/ide/stores/getters.js
ee/app/assets/javascripts/ide/stores/getters.js
+22
-16
ee/app/assets/javascripts/ide/stores/mutation_types.js
ee/app/assets/javascripts/ide/stores/mutation_types.js
+2
-3
ee/app/assets/javascripts/ide/stores/mutations.js
ee/app/assets/javascripts/ide/stores/mutations.js
+22
-5
ee/app/assets/javascripts/ide/stores/state.js
ee/app/assets/javascripts/ide/stores/state.js
+2
-0
spec/javascripts/ide/components/commit_sidebar/list_item_spec.js
...vascripts/ide/components/commit_sidebar/list_item_spec.js
+11
-0
spec/javascripts/ide/components/repo_editor_spec.js
spec/javascripts/ide/components/repo_editor_spec.js
+28
-0
spec/javascripts/ide/components/repo_tabs_spec.js
spec/javascripts/ide/components/repo_tabs_spec.js
+51
-1
spec/javascripts/ide/lib/common/model_manager_spec.js
spec/javascripts/ide/lib/common/model_manager_spec.js
+34
-0
spec/javascripts/ide/lib/common/model_spec.js
spec/javascripts/ide/lib/common/model_spec.js
+15
-0
spec/javascripts/ide/lib/editor_spec.js
spec/javascripts/ide/lib/editor_spec.js
+55
-12
spec/javascripts/ide/stores/actions/file_spec.js
spec/javascripts/ide/stores/actions/file_spec.js
+3
-0
spec/javascripts/ide/stores/actions_spec.js
spec/javascripts/ide/stores/actions_spec.js
+11
-0
spec/javascripts/ide/stores/modules/commit/actions_spec.js
spec/javascripts/ide/stores/modules/commit/actions_spec.js
+2
-0
spec/javascripts/ide/stores/mutations_spec.js
spec/javascripts/ide/stores/mutations_spec.js
+8
-0
No files found.
app/assets/javascripts/merge_request_tabs.js
View file @
174c2f80
...
...
@@ -73,6 +73,7 @@ export default class MergeRequestTabs {
constructor
({
action
,
setUrl
,
stubLocation
}
=
{})
{
const
mergeRequestTabs
=
document
.
querySelector
(
'
.js-tabs-affix
'
);
const
navbar
=
document
.
querySelector
(
'
.navbar-gitlab
'
);
const
peek
=
document
.
getElementById
(
'
peek
'
);
const
paddingTop
=
16
;
this
.
diffsLoaded
=
false
;
...
...
@@ -86,6 +87,10 @@ export default class MergeRequestTabs {
this
.
showTab
=
this
.
showTab
.
bind
(
this
);
this
.
stickyTop
=
navbar
?
navbar
.
offsetHeight
-
paddingTop
:
0
;
if
(
peek
)
{
this
.
stickyTop
+=
peek
.
offsetHeight
;
}
if
(
mergeRequestTabs
)
{
this
.
stickyTop
+=
mergeRequestTabs
.
offsetHeight
;
}
...
...
app/assets/stylesheets/pages/repo.scss
View file @
174c2f80
...
...
@@ -132,13 +132,35 @@
.multi-file-tabs
{
display
:
flex
;
overflow-x
:
auto
;
background-color
:
$white-normal
;
box-shadow
:
inset
0
-1px
$white-dark
;
>
li
{
>
ul
{
display
:
flex
;
overflow-x
:
auto
;
}
li
{
position
:
relative
;
}
.dropdown
{
display
:
flex
;
margin-left
:
auto
;
margin-bottom
:
1px
;
padding
:
0
$grid-size
;
border-left
:
1px
solid
$white-dark
;
background-color
:
$white-light
;
&
.shadow
{
box-shadow
:
0
0
10px
$dropdown-shadow-color
;
}
.btn
{
margin-top
:
auto
;
margin-bottom
:
auto
;
}
}
}
.multi-file-tab
{
...
...
@@ -207,6 +229,70 @@
.vertical-center
{
min-height
:
auto
;
}
.monaco-editor
.lines-content
.cigr
{
display
:
none
;
}
.monaco-diff-editor.vs
{
.editor.modified
{
box-shadow
:
none
;
}
.diagonal-fill
{
display
:
none
!
important
;
}
.diffOverview
{
background-color
:
$white-light
;
border-left
:
1px
solid
$white-dark
;
cursor
:
ns-resize
;
}
.diffViewport
{
display
:
none
;
}
.char-insert
{
background-color
:
$line-added-dark
;
}
.char-delete
{
background-color
:
$line-removed-dark
;
}
.line-numbers
{
color
:
$black-transparent
;
}
.view-overlays
{
.line-insert
{
background-color
:
$line-added
;
}
.line-delete
{
background-color
:
$line-removed
;
}
}
.margin
{
background-color
:
$gray-light
;
border-right
:
1px
solid
$white-normal
;
.line-insert
{
border-right
:
1px
solid
$line-added-dark
;
}
.line-delete
{
border-right
:
1px
solid
$line-removed-dark
;
}
}
.margin-view-overlays
.insert-sign
,
.margin-view-overlays
.delete-sign
{
opacity
:
.4
;
}
}
}
.multi-file-editor-holder
{
...
...
doc/administration/geo/replication/configuration.md
View file @
174c2f80
...
...
@@ -127,7 +127,11 @@ keys must be manually replicated to the secondary node.
1.
Restart sshd:
```bash
service ssh restart
# Debian or Ubuntu installations
sudo service ssh reload
# CentOS installations
sudo service sshd reload
```
### Step 3. Add the secondary GitLab node
...
...
doc/ci/examples/code_climate.md
View file @
174c2f80
...
...
@@ -16,18 +16,26 @@ codequality:
-
docker:dind
script
:
-
docker pull codeclimate/codeclimate
-
docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate:0.69.0 init
-
docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate:0.69.0 analyze -f json > codeclimate.json ||
true
-
export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
-
docker run
--env SOURCE_CODE="$PWD" \
--volume "$PWD":/code \
--volume /var/run/docker.sock:/var/run/docker.sock \
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts
:
paths
:
[
codeclimate.json
]
```
This will create a
`codequality`
job in your CI pipeline and will allow you to
download and analyze the report artifact in JSON format.
The above example will create a
`codequality`
job in your CI/CD pipeline which
will scan your source code for code quality issues. The report will be saved
as an artifact that you can later download and analyze.
For
[
GitLab Starter
][
ee
]
users, this information can be automatically
extracted and shown right in the merge request widget.
[
Learn more on code quality
diffs in merge requests
](
../../user/project/merge_requests/code_quality_diff.md
)
.
TIP:
**Tip:**
Starting with
[
GitLab Starter
][
ee
]
9.3, this information will
be automatically extracted and shown right in the merge request widget. To do
so, the CI/CD job must be named
`codequality`
and the artifact path must be
`codeclimate.json`
.
[
Learn more on code quality diffs in merge requests
](
../../user/project/merge_requests/code_quality_diff.md
)
.
[
cli
]:
https://github.com/codeclimate/codeclimate
[
dind
]:
../docker/using_docker_build.md#use-docker-in-docker-executor
...
...
doc/development/doc_styleguide.md
View file @
174c2f80
This diff is collapsed.
Click to expand it.
doc/development/writing_documentation.md
View file @
174c2f80
This diff is collapsed.
Click to expand it.
ee/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue
View file @
174c2f80
...
...
@@ -24,8 +24,11 @@
methods
:
{
...
mapActions
([
'
discardFileChanges
'
,
'
updateViewer
'
,
]),
openFileInEditor
(
file
)
{
this
.
updateViewer
(
'
diff
'
);
router
.
push
(
`/project
${
file
.
url
}
`
);
},
},
...
...
ee/app/assets/javascripts/ide/components/editor_mode_dropdown.vue
0 → 100644
View file @
174c2f80
<
script
>
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
export
default
{
components
:
{
Icon
,
},
props
:
{
hasChanges
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
viewer
:
{
type
:
String
,
required
:
true
,
},
showShadow
:
{
type
:
Boolean
,
required
:
true
,
},
},
methods
:
{
changeMode
(
mode
)
{
this
.
$emit
(
'
click
'
,
mode
);
},
},
};
</
script
>
<
template
>
<div
class=
"dropdown"
:class=
"
{
shadow: showShadow,
}"
>
<button
type=
"button"
class=
"btn btn-primary btn-sm"
:class=
"
{
'btn-inverted': hasChanges,
}"
data-toggle="dropdown"
>
<template
v-if=
"viewer === 'editor'"
>
{{
__
(
'
Editing
'
)
}}
</
template
>
<
template
v-else
>
{{
__
(
'
Reviewing
'
)
}}
</
template
>
<icon
name=
"angle-down"
:size=
"12"
css-classes=
"caret-down"
/>
</button>
<div
class=
"dropdown-menu dropdown-menu-selectable dropdown-open-left"
>
<ul>
<li>
<a
href=
"#"
@
click.prevent=
"changeMode('editor')"
:class=
"{
'is-active': viewer === 'editor',
}"
>
<strong
class=
"dropdown-menu-inner-title"
>
{{ __('Editing') }}
</strong>
<span
class=
"dropdown-menu-inner-content"
>
{{ __('View and edit lines') }}
</span>
</a>
</li>
<li>
<a
href=
"#"
@
click.prevent=
"changeMode('diff')"
:class=
"{
'is-active': viewer === 'diff',
}"
>
<strong
class=
"dropdown-menu-inner-title"
>
{{ __('Reviewing') }}
</strong>
<span
class=
"dropdown-menu-inner-content"
>
{{ __('Compare changes with the last commit') }}
</span>
</a>
</li>
</ul>
</div>
</div>
</template>
ee/app/assets/javascripts/ide/components/ide.vue
View file @
174c2f80
...
...
@@ -31,17 +31,12 @@
},
},
computed
:
{
...
mapState
([
'
changedFiles
'
,
'
openFiles
'
,
]),
...
mapGetters
([
'
activeFile
'
,
]),
...
mapState
([
'
changedFiles
'
,
'
openFiles
'
,
'
viewer
'
]),
...
mapGetters
([
'
activeFile
'
,
'
hasChanges
'
]),
},
mounted
()
{
const
returnValue
=
'
Are you sure you want to lose unsaved changes?
'
;
window
.
onbeforeunload
=
(
e
)
=>
{
window
.
onbeforeunload
=
e
=>
{
if
(
!
this
.
changedFiles
.
length
)
return
undefined
;
Object
.
assign
(
e
,
{
...
...
@@ -66,6 +61,8 @@
>
<repo-tabs
:files=
"openFiles"
:viewer=
"viewer"
:has-changes=
"hasChanges"
/>
<repo-editor
class=
"multi-file-edit-pane-content"
...
...
ee/app/assets/javascripts/ide/components/repo_editor.vue
View file @
174c2f80
...
...
@@ -16,6 +16,8 @@ export default {
...
mapState
([
'
leftPanelCollapsed
'
,
'
rightPanelCollapsed
'
,
'
viewer
'
,
'
delayViewerUpdated
'
,
]),
shouldHideEditor
()
{
return
this
.
file
&&
this
.
file
.
binary
&&
!
this
.
file
.
raw
;
...
...
@@ -33,6 +35,9 @@ export default {
rightPanelCollapsed
()
{
this
.
editor
.
updateDimensions
();
},
viewer
()
{
this
.
createEditorInstance
();
},
},
beforeDestroy
()
{
this
.
editor
.
dispose
();
...
...
@@ -55,6 +60,8 @@ export default {
'
setFileLanguage
'
,
'
setEditorPosition
'
,
'
setFileEOL
'
,
'
updateViewer
'
,
'
updateDelayViewerUpdated
'
,
]),
initMonaco
()
{
if
(
this
.
shouldHideEditor
)
return
;
...
...
@@ -63,16 +70,34 @@ export default {
this
.
getRawFileData
(
this
.
file
)
.
then
(()
=>
{
this
.
editor
.
createInstance
(
this
.
$refs
.
editor
);
const
viewerPromise
=
this
.
delayViewerUpdated
?
this
.
updateViewer
(
'
editor
'
)
:
Promise
.
resolve
();
return
viewerPromise
;
})
.
then
(()
=>
{
this
.
updateDelayViewerUpdated
(
false
);
this
.
createEditorInstance
();
})
.
then
(()
=>
this
.
setupEditor
())
.
catch
((
err
)
=>
{
flash
(
'
Error setting up monaco. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
);
throw
err
;
});
},
createEditorInstance
()
{
this
.
editor
.
dispose
();
this
.
$nextTick
(()
=>
{
if
(
this
.
viewer
===
'
editor
'
)
{
this
.
editor
.
createInstance
(
this
.
$refs
.
editor
);
}
else
{
this
.
editor
.
createDiffInstance
(
this
.
$refs
.
editor
);
}
this
.
setupEditor
();
});
},
setupEditor
()
{
if
(
!
this
.
file
)
return
;
if
(
!
this
.
file
||
!
this
.
editor
.
instance
)
return
;
this
.
model
=
this
.
editor
.
createModel
(
this
.
file
);
...
...
ee/app/assets/javascripts/ide/components/repo_file.vue
View file @
174c2f80
...
...
@@ -52,15 +52,23 @@
}
},
methods
:
{
...
mapActions
([
'
toggleTreeOpen
'
,
]),
...
mapActions
([
'
toggleTreeOpen
'
,
'
updateDelayViewerUpdated
'
]),
clickFile
()
{
// Manual Action if a tree is selected/opened
if
(
this
.
isTree
&&
this
.
$router
.
currentRoute
.
path
===
`/project
${
this
.
file
.
url
}
`
)
{
if
(
this
.
isTree
&&
this
.
$router
.
currentRoute
.
path
===
`/project
${
this
.
file
.
url
}
`
)
{
this
.
toggleTreeOpen
(
this
.
file
.
path
);
}
const
delayPromise
=
this
.
file
.
changed
?
Promise
.
resolve
()
:
this
.
updateDelayViewerUpdated
(
true
);
return
delayPromise
.
then
(()
=>
{
router
.
push
(
`/project
${
this
.
file
.
url
}
`
);
});
},
},
};
...
...
ee/app/assets/javascripts/ide/components/repo_tabs.vue
View file @
174c2f80
<
script
>
import
{
mapActions
}
from
'
vuex
'
;
import
RepoTab
from
'
./repo_tab.vue
'
;
import
EditorMode
from
'
./editor_mode_dropdown.vue
'
;
export
default
{
components
:
{
RepoTab
,
EditorMode
,
},
props
:
{
files
:
{
type
:
Array
,
required
:
true
,
},
viewer
:
{
type
:
String
,
required
:
true
,
},
hasChanges
:
{
type
:
Boolean
,
required
:
true
,
},
},
data
()
{
return
{
showShadow
:
false
,
};
},
updated
()
{
if
(
!
this
.
$refs
.
tabsScroller
)
return
;
this
.
showShadow
=
this
.
$refs
.
tabsScroller
.
scrollWidth
>
this
.
$refs
.
tabsScroller
.
offsetWidth
;
},
methods
:
{
...
mapActions
([
'
updateViewer
'
]),
},
};
</
script
>
<
template
>
<div
class=
"multi-file-tabs"
>
<ul
class=
"multi-file-tabs list-unstyled append-bottom-0"
class=
"list-unstyled append-bottom-0"
ref=
"tabsScroller"
>
<repo-tab
v-for=
"file
in files"
:key=
"file
.key"
:tab=
"file
"
v-for=
"tab
in files"
:key=
"tab
.key"
:tab=
"tab
"
/>
</ul>
<editor-mode
:viewer=
"viewer"
:show-shadow=
"showShadow"
:has-changes=
"hasChanges"
@
click=
"updateViewer"
/>
</div>
</
template
>
ee/app/assets/javascripts/ide/lib/common/model.js
View file @
174c2f80
...
...
@@ -26,6 +26,9 @@ export default class Model {
this
.
events
=
new
Map
();
this
.
updateContent
=
this
.
updateContent
.
bind
(
this
);
this
.
dispose
=
this
.
dispose
.
bind
(
this
);
eventHub
.
$on
(
`editor.update.model.dispose.
${
this
.
file
.
path
}
`
,
this
.
dispose
);
eventHub
.
$on
(
`editor.update.model.content.
${
this
.
file
.
path
}
`
,
this
.
updateContent
);
}
...
...
@@ -75,6 +78,7 @@ export default class Model {
this
.
disposable
.
dispose
();
this
.
events
.
clear
();
eventHub
.
$off
(
`editor.update.model.dispose.
${
this
.
file
.
path
}
`
,
this
.
dispose
);
eventHub
.
$off
(
`editor.update.model.content.
${
this
.
file
.
path
}
`
,
this
.
updateContent
);
}
}
ee/app/assets/javascripts/ide/lib/common/model_manager.js
View file @
174c2f80
import
eventHub
from
'
ee/ide/eventhub
'
;
import
Disposable
from
'
./disposable
'
;
import
Model
from
'
./model
'
;
...
...
@@ -25,9 +26,17 @@ export default class ModelManager {
this
.
models
.
set
(
model
.
path
,
model
);
this
.
disposable
.
add
(
model
);
eventHub
.
$on
(
`editor.update.model.dispose.
${
file
.
path
}
`
,
this
.
removeCachedModel
.
bind
(
this
,
file
));
return
model
;
}
removeCachedModel
(
file
)
{
this
.
models
.
delete
(
file
.
path
);
eventHub
.
$off
(
`editor.update.model.dispose.
${
file
.
path
}
`
,
this
.
removeCachedModel
);
}
dispose
()
{
// dispose of all the models
this
.
disposable
.
dispose
();
...
...
ee/app/assets/javascripts/ide/lib/decorations/controller.js
View file @
174c2f80
...
...
@@ -27,6 +27,8 @@ export default class DecorationsController {
}
decorate
(
model
)
{
if
(
!
this
.
editor
.
instance
)
return
;
const
decorations
=
this
.
getAllDecorationsForModel
(
model
);
const
oldDecorations
=
this
.
editorDecorations
.
get
(
model
.
url
)
||
[];
...
...
ee/app/assets/javascripts/ide/lib/editor.js
View file @
174c2f80
...
...
@@ -3,9 +3,16 @@ import DecorationsController from './decorations/controller';
import
DirtyDiffController
from
'
./diff/controller
'
;
import
Disposable
from
'
./common/disposable
'
;
import
ModelManager
from
'
./common/model_manager
'
;
import
editorOptions
from
'
./editor_options
'
;
import
editorOptions
,
{
defaultEditorOptions
}
from
'
./editor_options
'
;
import
gitlabTheme
from
'
./themes/gl_theme
'
;
import
gitlabTheme
from
'
ee/ide/lib/themes/gl_theme
'
;
// eslint-disable-line import/first
export
const
clearDomElement
=
el
=>
{
if
(
!
el
||
!
el
.
firstChild
)
return
;
while
(
el
.
firstChild
)
{
el
.
removeChild
(
el
.
firstChild
);
}
};
export
default
class
Editor
{
static
create
(
monaco
)
{
...
...
@@ -34,19 +41,31 @@ export default class Editor {
createInstance
(
domElement
)
{
if
(
!
this
.
instance
)
{
clearDomElement
(
domElement
);
this
.
disposable
.
add
(
this
.
instance
=
this
.
monaco
.
editor
.
create
(
domElement
,
{
model
:
null
,
readOnly
:
false
,
contextmenu
:
true
,
scrollBeyondLastLine
:
false
,
minimap
:
{
enabled
:
false
,
},
}),
this
.
dirtyDiffController
=
new
DirtyDiffController
(
this
.
modelManager
,
this
.
decorationsController
,
),
(
this
.
instance
=
this
.
monaco
.
editor
.
create
(
domElement
,
{
...
defaultEditorOptions
,
})),
(
this
.
dirtyDiffController
=
new
DirtyDiffController
(
this
.
modelManager
,
this
.
decorationsController
,
)),
);
window
.
addEventListener
(
'
resize
'
,
this
.
debouncedUpdate
,
false
);
}
}
createDiffInstance
(
domElement
)
{
if
(
!
this
.
instance
)
{
clearDomElement
(
domElement
);
this
.
disposable
.
add
(
(
this
.
instance
=
this
.
monaco
.
editor
.
createDiffEditor
(
domElement
,
{
...
defaultEditorOptions
,
readOnly
:
true
,
})),
);
window
.
addEventListener
(
'
resize
'
,
this
.
debouncedUpdate
,
false
);
...
...
@@ -58,25 +77,39 @@ export default class Editor {
}
attachModel
(
model
)
{
if
(
this
.
instance
.
getEditorType
()
===
'
vs.editor.IDiffEditor
'
)
{
this
.
instance
.
setModel
({
original
:
model
.
getOriginalModel
(),
modified
:
model
.
getModel
(),
});
return
;
}
this
.
instance
.
setModel
(
model
.
getModel
());
if
(
this
.
dirtyDiffController
)
this
.
dirtyDiffController
.
attachModel
(
model
);
this
.
currentModel
=
model
;
this
.
instance
.
updateOptions
(
editorOptions
.
reduce
((
acc
,
obj
)
=>
{
Object
.
keys
(
obj
).
forEach
((
key
)
=>
{
this
.
instance
.
updateOptions
(
editorOptions
.
reduce
((
acc
,
obj
)
=>
{
Object
.
keys
(
obj
).
forEach
(
key
=>
{
Object
.
assign
(
acc
,
{
[
key
]:
obj
[
key
](
model
),
});
});
return
acc
;
},
{}));
},
{}),
);
if
(
this
.
dirtyDiffController
)
this
.
dirtyDiffController
.
reDecorate
(
model
);
}
setupMonacoTheme
()
{
this
.
monaco
.
editor
.
defineTheme
(
gitlabTheme
.
themeName
,
gitlabTheme
.
monacoTheme
);
this
.
monaco
.
editor
.
defineTheme
(
gitlabTheme
.
themeName
,
gitlabTheme
.
monacoTheme
,
);
this
.
monaco
.
editor
.
setTheme
(
'
gitlab
'
);
}
...
...
@@ -88,12 +121,21 @@ export default class Editor {
}
dispose
()
{
this
.
disposable
.
dispose
();
window
.
removeEventListener
(
'
resize
'
,
this
.
debouncedUpdate
);
// dispose main monaco instance
if
(
this
.
instance
)
{
// catch any potential errors with disposing the error
// this is mainly for tests caused by elements not existing
try
{
this
.
disposable
.
dispose
();
this
.
instance
=
null
;
}
catch
(
e
)
{
this
.
instance
=
null
;
if
(
process
.
env
.
NODE_ENV
!==
'
test
'
)
{
// eslint-disable-next-line no-console
console
.
error
(
e
);
}
}
}
...
...
@@ -113,6 +155,8 @@ export default class Editor {
}
onPositionChange
(
cb
)
{
if
(
!
this
.
instance
.
onDidChangeCursorPosition
)
return
;
this
.
disposable
.
add
(
this
.
instance
.
onDidChangeCursorPosition
(
e
=>
cb
(
this
.
instance
,
e
)),
);
...
...
ee/app/assets/javascripts/ide/lib/editor_options.js
View file @
174c2f80
export
default
[{
export
const
defaultEditorOptions
=
{
model
:
null
,
readOnly
:
false
,
contextmenu
:
true
,
scrollBeyondLastLine
:
false
,
minimap
:
{
enabled
:
false
,
},
};
export
default
[
{
readOnly
:
model
=>
!!
model
.
file
.
file_lock
,
}];
},
];
ee/app/assets/javascripts/ide/lib/themes/gl_theme.js
View file @
174c2f80
...
...
@@ -6,6 +6,9 @@ export default {
rules
:
[],
colors
:
{
'
editorLineNumber.foreground
'
:
'
#CCCCCC
'
,
'
diffEditor.insertedTextBackground
'
:
'
#ddfbe6
'
,
'
diffEditor.removedTextBackground
'
:
'
#f9d7dc
'
,
'
editor.selectionBackground
'
:
'
#aad6f8
'
,
},
},
};
ee/app/assets/javascripts/ide/stores/actions.js
View file @
174c2f80
...
...
@@ -108,6 +108,14 @@ export const scrollToTab = () => {
});
};
export
const
updateViewer
=
({
commit
},
viewer
)
=>
{
commit
(
types
.
UPDATE_VIEWER
,
viewer
);
};
export
const
updateDelayViewerUpdated
=
({
commit
},
delay
)
=>
{
commit
(
types
.
UPDATE_DELAY_VIEWER_CHANGE
,
delay
);
};
export
*
from
'
./actions/tree
'
;
export
*
from
'
./actions/file
'
;
export
*
from
'
./actions/project
'
;
ee/app/assets/javascripts/ide/stores/actions/file.js
View file @
174c2f80
import
{
normalizeHeaders
}
from
'
~/lib/utils/common_utils
'
;
import
flash
from
'
~/flash
'
;
import
eventHub
from
'
ee/ide/eventhub
'
;
import
service
from
'
../../services
'
;
import
*
as
types
from
'
../mutation_types
'
;
import
router
from
'
../../ide_router
'
;
import
{
setPageTitle
,
}
from
'
../utils
'
;
import
{
setPageTitle
}
from
'
../utils
'
;
export
const
closeFile
=
({
commit
,
state
,
getters
,
dispatch
},
path
)
=>
{
const
indexOfClosedFile
=
state
.
openFiles
.
indexOf
(
path
);
...
...
@@ -23,6 +22,8 @@ export const closeFile = ({ commit, state, getters, dispatch }, path) => {
}
else
if
(
!
state
.
openFiles
.
length
)
{
router
.
push
(
`/project/
${
file
.
projectId
}
/tree/
${
file
.
branchId
}
/`
);
}
eventHub
.
$emit
(
`editor.update.model.dispose.
${
file
.
path
}
`
);
};
export
const
setFileActive
=
({
commit
,
state
,
getters
,
dispatch
},
path
)
=>
{
...
...
@@ -32,7 +33,10 @@ export const setFileActive = ({ commit, state, getters, dispatch }, path) => {
if
(
file
.
active
)
return
;
if
(
currentActiveFile
)
{
commit
(
types
.
SET_FILE_ACTIVE
,
{
path
:
currentActiveFile
.
path
,
active
:
false
});
commit
(
types
.
SET_FILE_ACTIVE
,
{
path
:
currentActiveFile
.
path
,
active
:
false
,
});
}
commit
(
types
.
SET_FILE_ACTIVE
,
{
path
,
active
:
true
});
...
...
@@ -45,15 +49,16 @@ export const setFileActive = ({ commit, state, getters, dispatch }, path) => {
export
const
getFileData
=
({
state
,
commit
,
dispatch
},
file
)
=>
{
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
return
service
.
getFileData
(
file
.
url
)
.
then
((
res
)
=>
{
return
service
.
getFileData
(
file
.
url
)
.
then
(
res
=>
{
const
pageTitle
=
decodeURI
(
normalizeHeaders
(
res
.
headers
)[
'
PAGE-TITLE
'
]);
setPageTitle
(
pageTitle
);
return
res
.
json
();
})
.
then
(
(
data
)
=>
{
.
then
(
data
=>
{
commit
(
types
.
SET_FILE_DATA
,
{
data
,
file
});
commit
(
types
.
TOGGLE_FILE_OPEN
,
file
.
path
);
dispatch
(
'
setFileActive
'
,
file
.
path
);
...
...
@@ -61,15 +66,33 @@ export const getFileData = ({ state, commit, dispatch }, file) => {
})
.
catch
(()
=>
{
commit
(
types
.
TOGGLE_LOADING
,
{
entry
:
file
});
flash
(
'
Error loading file data. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
);
flash
(
'
Error loading file data. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
,
);
});
};
export
const
getRawFileData
=
({
commit
,
dispatch
},
file
)
=>
service
.
getRawFileData
(
file
)
.
then
((
raw
)
=>
{
export
const
getRawFileData
=
({
commit
,
dispatch
},
file
)
=>
service
.
getRawFileData
(
file
)
.
then
(
raw
=>
{
commit
(
types
.
SET_FILE_RAW_DATA
,
{
file
,
raw
});
})
.
catch
(()
=>
flash
(
'
Error loading file content. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
));
.
catch
(()
=>
flash
(
'
Error loading file content. Please try again.
'
,
'
alert
'
,
document
,
null
,
false
,
true
,
),
);
export
const
changeFileContent
=
({
state
,
commit
},
{
path
,
content
})
=>
{
const
file
=
state
.
entries
[
path
];
...
...
@@ -96,9 +119,16 @@ export const setFileEOL = ({ getters, commit }, { eol }) => {
}
};
export
const
setEditorPosition
=
({
getters
,
commit
},
{
editorRow
,
editorColumn
})
=>
{
export
const
setEditorPosition
=
(
{
getters
,
commit
},
{
editorRow
,
editorColumn
},
)
=>
{
if
(
getters
.
activeFile
)
{
commit
(
types
.
SET_FILE_POSITION
,
{
file
:
getters
.
activeFile
,
editorRow
,
editorColumn
});
commit
(
types
.
SET_FILE_POSITION
,
{
file
:
getters
.
activeFile
,
editorRow
,
editorColumn
,
});
}
};
...
...
@@ -111,4 +141,6 @@ export const discardFileChanges = ({ state, commit }, path) => {
if
(
file
.
tempFile
&&
file
.
opened
)
{
commit
(
types
.
TOGGLE_FILE_OPEN
,
path
);
}
eventHub
.
$emit
(
`editor.update.model.content.
${
file
.
path
}
`
,
file
.
raw
);
};
ee/app/assets/javascripts/ide/stores/getters.js
View file @
174c2f80
export
const
activeFile
=
state
=>
state
.
openFiles
.
find
(
file
=>
file
.
active
)
||
null
;
export
const
activeFile
=
state
=>
state
.
openFiles
.
find
(
file
=>
file
.
active
)
||
null
;
export
const
addedFiles
=
state
=>
state
.
changedFiles
.
filter
(
f
=>
f
.
tempFile
);
export
const
modifiedFiles
=
state
=>
state
.
changedFiles
.
filter
(
f
=>
!
f
.
tempFile
);
export
const
modifiedFiles
=
state
=>
state
.
changedFiles
.
filter
(
f
=>
!
f
.
tempFile
);
export
const
projectsWithTrees
=
state
=>
Object
.
keys
(
state
.
projects
).
map
((
projectId
)
=>
{
export
const
projectsWithTrees
=
state
=>
Object
.
keys
(
state
.
projects
).
map
(
projectId
=>
{
const
project
=
state
.
projects
[
projectId
];
return
{
...
project
,
branches
:
Object
.
keys
(
project
.
branches
).
map
((
branchId
)
=>
{
branches
:
Object
.
keys
(
project
.
branches
).
map
(
branchId
=>
{
const
branch
=
project
.
branches
[
branchId
];
return
{
...
...
@@ -18,7 +21,10 @@ export const projectsWithTrees = state => Object.keys(state.projects).map((proje
};
}),
};
});
});
// eslint-disable-next-line no-confusing-arrow
export
const
currentIcon
=
state
=>
(
state
.
rightPanelCollapsed
?
'
angle-double-left
'
:
'
angle-double-right
'
);
state
.
rightPanelCollapsed
?
'
angle-double-left
'
:
'
angle-double-right
'
;
export
const
hasChanges
=
state
=>
!!
state
.
changedFiles
.
length
;
ee/app/assets/javascripts/ide/stores/mutation_types.js
View file @
174c2f80
...
...
@@ -36,9 +36,8 @@ export const DISCARD_FILE_CHANGES = 'DISCARD_FILE_CHANGES';
export
const
ADD_FILE_TO_CHANGED
=
'
ADD_FILE_TO_CHANGED
'
;
export
const
REMOVE_FILE_FROM_CHANGED
=
'
REMOVE_FILE_FROM_CHANGED
'
;
export
const
TOGGLE_FILE_CHANGED
=
'
TOGGLE_FILE_CHANGED
'
;
export
const
SET_CURRENT_BRANCH
=
'
SET_CURRENT_BRANCH
'
;
export
const
SET_ENTRIES
=
'
SET_ENTRIES
'
;
export
const
CREATE_TMP_ENTRY
=
'
CREATE_TMP_ENTRY
'
;
export
const
UPDATE_VIEWER
=
'
UPDATE_VIEWER
'
;
export
const
UPDATE_DELAY_VIEWER_CHANGE
=
'
UPDATE_DELAY_VIEWER_CHANGE
'
;
ee/app/assets/javascripts/ide/stores/mutations.js
View file @
174c2f80
...
...
@@ -11,7 +11,10 @@ export default {
[
types
.
TOGGLE_LOADING
](
state
,
{
entry
,
forceValue
=
undefined
})
{
if
(
entry
.
path
)
{
Object
.
assign
(
state
.
entries
[
entry
.
path
],
{
loading
:
forceValue
!==
undefined
?
forceValue
:
!
state
.
entries
[
entry
.
path
].
loading
,
loading
:
forceValue
!==
undefined
?
forceValue
:
!
state
.
entries
[
entry
.
path
].
loading
,
});
}
else
{
Object
.
assign
(
entry
,
{
...
...
@@ -63,8 +66,8 @@ export default {
[
key
]:
entry
,
});
}
else
{
const
tree
=
entry
.
tree
.
filter
(
f
=>
foundEntry
.
tree
.
find
(
e
=>
e
.
path
===
f
.
path
)
===
undefined
,
const
tree
=
entry
.
tree
.
filter
(
f
=>
f
oundEntry
.
tree
.
find
(
e
=>
e
.
path
===
f
.
path
)
===
undefined
,
);
Object
.
assign
(
foundEntry
,
{
tree
:
foundEntry
.
tree
.
concat
(
tree
),
...
...
@@ -74,14 +77,28 @@ export default {
return
acc
.
concat
(
key
);
},
[]);
const
foundEntry
=
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
].
tree
.
find
(
e
=>
e
.
path
===
data
.
treeList
[
0
].
path
);
const
foundEntry
=
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
].
tree
.
find
(
e
=>
e
.
path
===
data
.
treeList
[
0
].
path
,
);
if
(
!
foundEntry
)
{
Object
.
assign
(
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
],
{
tree
:
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
].
tree
.
concat
(
data
.
treeList
),
tree
:
state
.
trees
[
`
${
projectId
}
/
${
branchId
}
`
].
tree
.
concat
(
data
.
treeList
,
),
});
}
},
[
types
.
UPDATE_VIEWER
](
state
,
viewer
)
{
Object
.
assign
(
state
,
{
viewer
,
});
},
[
types
.
UPDATE_DELAY_VIEWER_CHANGE
](
state
,
delayViewerUpdated
)
{
Object
.
assign
(
state
,
{
delayViewerUpdated
,
});
},
...
projectMutations
,
...
fileMutations
,
...
treeMutations
,
...
...
ee/app/assets/javascripts/ide/stores/state.js
View file @
174c2f80
...
...
@@ -14,4 +14,6 @@ export default () => ({
rightPanelCollapsed
:
false
,
panelResizing
:
false
,
entries
:
{},
viewer
:
'
editor
'
,
delayViewerUpdated
:
false
,
});
spec/javascripts/ide/components/commit_sidebar/list_item_spec.js
View file @
174c2f80
...
...
@@ -36,6 +36,7 @@ describe('Multi-file editor commit sidebar list item', () => {
it
(
'
opens a closed file in the editor when clicking the file path
'
,
()
=>
{
spyOn
(
vm
,
'
openFileInEditor
'
).
and
.
callThrough
();
spyOn
(
vm
,
'
updateViewer
'
);
spyOn
(
router
,
'
push
'
);
vm
.
$el
.
querySelector
(
'
.multi-file-commit-list-path
'
).
click
();
...
...
@@ -44,6 +45,16 @@ describe('Multi-file editor commit sidebar list item', () => {
expect
(
router
.
push
).
toHaveBeenCalled
();
});
it
(
'
calls updateViewer with diff when clicking file
'
,
()
=>
{
spyOn
(
vm
,
'
openFileInEditor
'
).
and
.
callThrough
();
spyOn
(
vm
,
'
updateViewer
'
);
spyOn
(
router
,
'
push
'
);
vm
.
$el
.
querySelector
(
'
.multi-file-commit-list-path
'
).
click
();
expect
(
vm
.
updateViewer
).
toHaveBeenCalledWith
(
'
diff
'
);
});
describe
(
'
computed
'
,
()
=>
{
describe
(
'
iconName
'
,
()
=>
{
it
(
'
returns modified when not a tempFile
'
,
()
=>
{
...
...
spec/javascripts/ide/components/repo_editor_spec.js
View file @
174c2f80
...
...
@@ -63,6 +63,34 @@ describe('RepoEditor', () => {
});
});
describe
(
'
createEditorInstance
'
,
()
=>
{
it
(
'
calls createInstance when viewer is editor
'
,
(
done
)
=>
{
spyOn
(
vm
.
editor
,
'
createInstance
'
);
vm
.
createEditorInstance
();
vm
.
$nextTick
(()
=>
{
expect
(
vm
.
editor
.
createInstance
).
toHaveBeenCalled
();
done
();
});
});
it
(
'
calls createDiffInstance when viewer is diff
'
,
(
done
)
=>
{
vm
.
$store
.
state
.
viewer
=
'
diff
'
;
spyOn
(
vm
.
editor
,
'
createDiffInstance
'
);
vm
.
createEditorInstance
();
vm
.
$nextTick
(()
=>
{
expect
(
vm
.
editor
.
createDiffInstance
).
toHaveBeenCalled
();
done
();
});
});
});
describe
(
'
setupEditor
'
,
()
=>
{
it
(
'
creates new model
'
,
()
=>
{
spyOn
(
vm
.
editor
,
'
createModel
'
).
and
.
callThrough
();
...
...
spec/javascripts/ide/components/repo_tabs_spec.js
View file @
174c2f80
...
...
@@ -12,9 +12,11 @@ describe('RepoTabs', () => {
vm
.
$destroy
();
});
it
(
'
renders a list of tabs
'
,
(
done
)
=>
{
it
(
'
renders a list of tabs
'
,
done
=>
{
vm
=
createComponent
(
RepoTabs
,
{
files
:
openedFiles
,
viewer
:
'
editor
'
,
hasChanges
:
false
,
});
openedFiles
[
0
].
active
=
true
;
...
...
@@ -28,4 +30,52 @@ describe('RepoTabs', () => {
done
();
});
});
describe
(
'
updated
'
,
()
=>
{
it
(
'
sets showShadow as true when scroll width is larger than width
'
,
done
=>
{
const
el
=
document
.
createElement
(
'
div
'
);
el
.
innerHTML
=
'
<div id="test-app"></div>
'
;
document
.
body
.
appendChild
(
el
);
const
style
=
document
.
createElement
(
'
style
'
);
style
.
innerText
=
`
.multi-file-tabs {
width: 100px;
}
.multi-file-tabs .list-unstyled {
display: flex;
overflow-x: auto;
}
`
;
document
.
head
.
appendChild
(
style
);
vm
=
createComponent
(
RepoTabs
,
{
files
:
[],
viewer
:
'
editor
'
,
hasChanges
:
false
,
},
'
#test-app
'
,
);
vm
.
$nextTick
()
.
then
(()
=>
{
expect
(
vm
.
showShadow
).
toEqual
(
false
);
vm
.
files
=
openedFiles
;
})
.
then
(
vm
.
$nextTick
)
.
then
(()
=>
{
expect
(
vm
.
showShadow
).
toEqual
(
true
);
style
.
remove
();
el
.
remove
();
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
});
spec/javascripts/ide/lib/common/model_manager_spec.js
View file @
174c2f80
/* global monaco */
import
eventHub
from
'
ee/ide/eventhub
'
;
import
monacoLoader
from
'
ee/ide/monaco_loader
'
;
import
ModelManager
from
'
ee/ide/lib/common/model_manager
'
;
import
{
file
}
from
'
../../helpers
'
;
...
...
@@ -47,6 +48,15 @@ describe('Multi-file editor library model manager', () => {
expect
(
instance
.
models
.
get
).
toHaveBeenCalled
();
});
it
(
'
adds eventHub listener
'
,
()
=>
{
const
f
=
file
();
spyOn
(
eventHub
,
'
$on
'
).
and
.
callThrough
();
instance
.
addModel
(
f
);
expect
(
eventHub
.
$on
).
toHaveBeenCalledWith
(
`editor.update.model.dispose.
${
f
.
path
}
`
,
jasmine
.
anything
());
});
});
describe
(
'
hasCachedModel
'
,
()
=>
{
...
...
@@ -69,6 +79,30 @@ describe('Multi-file editor library model manager', () => {
});
});
describe
(
'
removeCachedModel
'
,
()
=>
{
let
f
;
beforeEach
(()
=>
{
f
=
file
();
instance
.
addModel
(
f
);
});
it
(
'
clears cached model
'
,
()
=>
{
instance
.
removeCachedModel
(
f
);
expect
(
instance
.
models
.
size
).
toBe
(
0
);
});
it
(
'
removes eventHub listener
'
,
()
=>
{
spyOn
(
eventHub
,
'
$off
'
).
and
.
callThrough
();
instance
.
removeCachedModel
(
f
);
expect
(
eventHub
.
$off
).
toHaveBeenCalledWith
(
`editor.update.model.dispose.
${
f
.
path
}
`
,
jasmine
.
anything
());
});
});
describe
(
'
dispose
'
,
()
=>
{
it
(
'
clears cached models
'
,
()
=>
{
instance
.
addModel
(
file
());
...
...
spec/javascripts/ide/lib/common/model_spec.js
View file @
174c2f80
/* global monaco */
import
eventHub
from
'
ee/ide/eventhub
'
;
import
monacoLoader
from
'
ee/ide/monaco_loader
'
;
import
Model
from
'
ee/ide/lib/common/model
'
;
import
{
file
}
from
'
../../helpers
'
;
...
...
@@ -7,6 +8,8 @@ describe('Multi-file editor library model', () => {
let
model
;
beforeEach
((
done
)
=>
{
spyOn
(
eventHub
,
'
$on
'
).
and
.
callThrough
();
monacoLoader
([
'
vs/editor/editor.main
'
],
()
=>
{
model
=
new
Model
(
monaco
,
file
(
'
path
'
));
...
...
@@ -23,6 +26,10 @@ describe('Multi-file editor library model', () => {
expect
(
model
.
model
).
not
.
toBeNull
();
});
it
(
'
adds eventHub listener
'
,
()
=>
{
expect
(
eventHub
.
$on
).
toHaveBeenCalledWith
(
`editor.update.model.dispose.
${
model
.
file
.
path
}
`
,
jasmine
.
anything
());
});
describe
(
'
path
'
,
()
=>
{
it
(
'
returns file path
'
,
()
=>
{
expect
(
model
.
path
).
toBe
(
'
path
'
);
...
...
@@ -88,5 +95,13 @@ describe('Multi-file editor library model', () => {
expect
(
model
.
events
.
size
).
toBe
(
0
);
});
it
(
'
removes eventHub listener
'
,
()
=>
{
spyOn
(
eventHub
,
'
$off
'
).
and
.
callThrough
();
model
.
dispose
();
expect
(
eventHub
.
$off
).
toHaveBeenCalledWith
(
`editor.update.model.dispose.
${
model
.
file
.
path
}
`
,
jasmine
.
anything
());
});
});
});
spec/javascripts/ide/lib/editor_spec.js
View file @
174c2f80
...
...
@@ -5,8 +5,16 @@ import { file } from '../helpers';
describe
(
'
Multi-file editor library
'
,
()
=>
{
let
instance
;
let
el
;
let
holder
;
beforeEach
(
done
=>
{
el
=
document
.
createElement
(
'
div
'
);
holder
=
document
.
createElement
(
'
div
'
);
el
.
appendChild
(
holder
);
document
.
body
.
appendChild
(
el
);
beforeEach
((
done
)
=>
{
monacoLoader
([
'
vs/editor/editor.main
'
],
()
=>
{
instance
=
editor
.
create
(
monaco
);
...
...
@@ -16,6 +24,8 @@ describe('Multi-file editor library', () => {
afterEach
(()
=>
{
instance
.
dispose
();
el
.
remove
();
});
it
(
'
creates instance of editor
'
,
()
=>
{
...
...
@@ -27,33 +37,48 @@ describe('Multi-file editor library', () => {
});
describe
(
'
createInstance
'
,
()
=>
{
let
el
;
beforeEach
(()
=>
{
el
=
document
.
createElement
(
'
div
'
);
});
it
(
'
creates editor instance
'
,
()
=>
{
spyOn
(
instance
.
monaco
.
editor
,
'
create
'
).
and
.
callThrough
();
instance
.
createInstance
(
el
);
instance
.
createInstance
(
holder
);
expect
(
instance
.
monaco
.
editor
.
create
).
toHaveBeenCalled
();
});
it
(
'
creates dirty diff controller
'
,
()
=>
{
instance
.
createInstance
(
el
);
instance
.
createInstance
(
holder
);
expect
(
instance
.
dirtyDiffController
).
not
.
toBeNull
();
});
it
(
'
creates model manager
'
,
()
=>
{
instance
.
createInstance
(
el
);
instance
.
createInstance
(
holder
);
expect
(
instance
.
modelManager
).
not
.
toBeNull
();
});
});
describe
(
'
createDiffInstance
'
,
()
=>
{
it
(
'
creates editor instance
'
,
()
=>
{
spyOn
(
instance
.
monaco
.
editor
,
'
createDiffEditor
'
).
and
.
callThrough
();
instance
.
createDiffInstance
(
holder
);
expect
(
instance
.
monaco
.
editor
.
createDiffEditor
).
toHaveBeenCalledWith
(
holder
,
{
model
:
null
,
contextmenu
:
true
,
minimap
:
{
enabled
:
false
,
},
readOnly
:
true
,
scrollBeyondLastLine
:
false
,
},
);
});
});
describe
(
'
createModel
'
,
()
=>
{
it
(
'
calls model manager addModel
'
,
()
=>
{
spyOn
(
instance
.
modelManager
,
'
addModel
'
);
...
...
@@ -87,12 +112,28 @@ describe('Multi-file editor library', () => {
expect
(
instance
.
instance
.
setModel
).
toHaveBeenCalledWith
(
model
.
getModel
());
});
it
(
'
sets original & modified when diff editor
'
,
()
=>
{
spyOn
(
instance
.
instance
,
'
getEditorType
'
).
and
.
returnValue
(
'
vs.editor.IDiffEditor
'
,
);
spyOn
(
instance
.
instance
,
'
setModel
'
);
instance
.
attachModel
(
model
);
expect
(
instance
.
instance
.
setModel
).
toHaveBeenCalledWith
({
original
:
model
.
getOriginalModel
(),
modified
:
model
.
getModel
(),
});
});
it
(
'
attaches the model to the dirty diff controller
'
,
()
=>
{
spyOn
(
instance
.
dirtyDiffController
,
'
attachModel
'
);
instance
.
attachModel
(
model
);
expect
(
instance
.
dirtyDiffController
.
attachModel
).
toHaveBeenCalledWith
(
model
);
expect
(
instance
.
dirtyDiffController
.
attachModel
).
toHaveBeenCalledWith
(
model
,
);
});
it
(
'
re-decorates with the dirty diff controller
'
,
()
=>
{
...
...
@@ -100,7 +141,9 @@ describe('Multi-file editor library', () => {
instance
.
attachModel
(
model
);
expect
(
instance
.
dirtyDiffController
.
reDecorate
).
toHaveBeenCalledWith
(
model
);
expect
(
instance
.
dirtyDiffController
.
reDecorate
).
toHaveBeenCalledWith
(
model
,
);
});
});
...
...
spec/javascripts/ide/stores/actions/file_spec.js
View file @
174c2f80
...
...
@@ -2,6 +2,7 @@ import Vue from 'vue';
import
store
from
'
ee/ide/stores
'
;
import
service
from
'
ee/ide/services
'
;
import
router
from
'
ee/ide/ide_router
'
;
import
eventHub
from
'
ee/ide/eventhub
'
;
import
{
file
,
resetStore
}
from
'
../../helpers
'
;
describe
(
'
Multi-file store file actions
'
,
()
=>
{
...
...
@@ -295,6 +296,8 @@ describe('Multi-file store file actions', () => {
let
tmpFile
;
beforeEach
(()
=>
{
spyOn
(
eventHub
,
'
$on
'
);
tmpFile
=
file
();
tmpFile
.
content
=
'
testing
'
;
...
...
spec/javascripts/ide/stores/actions_spec.js
View file @
174c2f80
...
...
@@ -291,4 +291,15 @@ describe('Multi-file store actions', () => {
.
catch
(
done
.
fail
);
});
});
describe
(
'
updateViewer
'
,
()
=>
{
it
(
'
updates viewer state
'
,
(
done
)
=>
{
store
.
dispatch
(
'
updateViewer
'
,
'
diff
'
)
.
then
(()
=>
{
expect
(
store
.
state
.
viewer
).
toBe
(
'
diff
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
});
spec/javascripts/ide/stores/modules/commit/actions_spec.js
View file @
174c2f80
...
...
@@ -409,6 +409,8 @@ describe('IDE commit module actions', () => {
});
it
(
'
redirects to new merge request page
'
,
(
done
)
=>
{
spyOn
(
eventHub
,
'
$on
'
);
store
.
state
.
commit
.
commitAction
=
'
3
'
;
store
.
dispatch
(
'
commit/commitChanges
'
)
...
...
spec/javascripts/ide/stores/mutations_spec.js
View file @
174c2f80
...
...
@@ -68,4 +68,12 @@ describe('Multi-file store mutations', () => {
expect
(
localState
.
rightPanelCollapsed
).
toBeFalsy
();
});
});
describe
(
'
UPDATE_VIEWER
'
,
()
=>
{
it
(
'
sets viewer state
'
,
()
=>
{
mutations
.
UPDATE_VIEWER
(
localState
,
'
diff
'
);
expect
(
localState
.
viewer
).
toBe
(
'
diff
'
);
});
});
});
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