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
0
Merge Requests
0
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
Jérome Perrin
gitlab-ce
Commits
60ebd101
Commit
60ebd101
authored
Apr 13, 2017
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use blob viewers for snippets
parent
c2059737
Changes
30
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
478 additions
and
76 deletions
+478
-76
app/assets/javascripts/blob/viewer/index.js
app/assets/javascripts/blob/viewer/index.js
+2
-2
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+6
-0
app/assets/javascripts/line_highlighter.js
app/assets/javascripts/line_highlighter.js
+3
-3
app/controllers/concerns/renders_blob.rb
app/controllers/concerns/renders_blob.rb
+4
-0
app/controllers/projects/blob_controller.rb
app/controllers/projects/blob_controller.rb
+1
-1
app/controllers/projects/snippets_controller.rb
app/controllers/projects/snippets_controller.rb
+18
-5
app/controllers/snippets_controller.rb
app/controllers/snippets_controller.rb
+13
-0
app/helpers/blob_helper.rb
app/helpers/blob_helper.rb
+11
-3
app/models/snippet.rb
app/models/snippet.rb
+2
-24
app/models/snippet_blob.rb
app/models/snippet_blob.rb
+59
-0
app/views/projects/blob/_header.html.haml
app/views/projects/blob/_header.html.haml
+1
-1
app/views/projects/blob/viewers/_markup.html.haml
app/views/projects/blob/viewers/_markup.html.haml
+2
-1
app/views/projects/snippets/show.html.haml
app/views/projects/snippets/show.html.haml
+1
-1
app/views/search/results/_snippet_blob.html.haml
app/views/search/results/_snippet_blob.html.haml
+1
-1
app/views/shared/snippets/_blob.html.haml
app/views/shared/snippets/_blob.html.haml
+12
-17
app/views/snippets/show.html.haml
app/views/snippets/show.html.haml
+1
-1
features/project/snippets.feature
features/project/snippets.feature
+1
-0
features/snippets/snippets.feature
features/snippets/snippets.feature
+1
-0
features/steps/project/snippets.rb
features/steps/project/snippets.rb
+4
-1
features/steps/snippets/snippets.rb
features/steps/snippets/snippets.rb
+3
-1
spec/features/projects/blobs/blob_show_spec.rb
spec/features/projects/blobs/blob_show_spec.rb
+5
-8
spec/features/projects/snippets/show_spec.rb
spec/features/projects/snippets/show_spec.rb
+132
-0
spec/features/snippets/create_snippet_spec.rb
spec/features/snippets/create_snippet_spec.rb
+5
-3
spec/features/snippets/public_snippets_spec.rb
spec/features/snippets/public_snippets_spec.rb
+2
-1
spec/features/snippets/show_spec.rb
spec/features/snippets/show_spec.rb
+126
-0
spec/helpers/blob_helper_spec.rb
spec/helpers/blob_helper_spec.rb
+1
-0
spec/javascripts/fixtures/line_highlighter.html.haml
spec/javascripts/fixtures/line_highlighter.html.haml
+1
-1
spec/models/snippet_blob_spec.rb
spec/models/snippet_blob_spec.rb
+47
-0
spec/models/snippet_spec.rb
spec/models/snippet_spec.rb
+12
-1
spec/views/projects/blob/_viewer.html.haml_spec.rb
spec/views/projects/blob/_viewer.html.haml_spec.rb
+1
-0
No files found.
app/assets/javascripts/blob/viewer/index.js
View file @
60ebd101
...
...
@@ -6,7 +6,7 @@ export default class BlobViewer {
this
.
copySourceBtn
=
document
.
querySelector
(
'
.js-copy-blob-source-btn
'
);
this
.
simpleViewer
=
document
.
querySelector
(
'
.blob-viewer[data-type="simple"]
'
);
this
.
richViewer
=
document
.
querySelector
(
'
.blob-viewer[data-type="rich"]
'
);
this
.
$
blobContentHolder
=
$
(
'
#blob-content
-holder
'
);
this
.
$
fileHolder
=
$
(
'
.file
-holder
'
);
let
initialViewerName
=
document
.
querySelector
(
'
.blob-viewer:not(.hidden)
'
).
getAttribute
(
'
data-type
'
);
...
...
@@ -82,7 +82,7 @@ export default class BlobViewer {
viewer
.
setAttribute
(
'
data-loaded
'
,
'
true
'
);
this
.
$
blobContent
Holder
.
trigger
(
'
highlight:line
'
);
this
.
$
file
Holder
.
trigger
(
'
highlight:line
'
);
this
.
toggleCopyButtonState
();
});
...
...
app/assets/javascripts/dispatcher.js
View file @
60ebd101
...
...
@@ -356,6 +356,10 @@ const ShortcutsBlob = require('./shortcuts_blob');
case
'
users:show
'
:
new
UserCallout
();
break
;
case
'
snippets:show
'
:
new
LineHighlighter
();
new
BlobViewer
();
break
;
}
switch
(
path
.
first
())
{
case
'
sessions
'
:
...
...
@@ -434,6 +438,8 @@ const ShortcutsBlob = require('./shortcuts_blob');
shortcut_handler
=
new
ShortcutsNavigation
();
if
(
path
[
2
]
===
'
show
'
)
{
new
ZenMode
();
new
LineHighlighter
();
new
BlobViewer
();
}
break
;
case
'
labels
'
:
...
...
app/assets/javascripts/line_highlighter.js
View file @
60ebd101
...
...
@@ -57,9 +57,9 @@ require('vendor/jquery.scrollTo');
}
LineHighlighter
.
prototype
.
bindEvents
=
function
()
{
const
$
blobContentHolder
=
$
(
'
#blob-content
-holder
'
);
$
blobContent
Holder
.
on
(
'
click
'
,
'
a[data-line-number]
'
,
this
.
clickHandler
);
$
blobContent
Holder
.
on
(
'
highlight:line
'
,
this
.
highlightHash
);
const
$
fileHolder
=
$
(
'
.file
-holder
'
);
$
file
Holder
.
on
(
'
click
'
,
'
a[data-line-number]
'
,
this
.
clickHandler
);
$
file
Holder
.
on
(
'
highlight:line
'
,
this
.
highlightHash
);
};
LineHighlighter
.
prototype
.
highlightHash
=
function
()
{
...
...
app/controllers/concerns/renders_blob.rb
View file @
60ebd101
...
...
@@ -14,4 +14,8 @@ module RendersBlob
html:
view_to_html_string
(
"projects/blob/_viewer"
,
viewer:
viewer
,
load_asynchronously:
false
)
}
end
def
override_max_blob_size
(
blob
)
blob
.
override_max_size!
if
params
[
:override_max_size
]
==
'true'
end
end
app/controllers/projects/blob_controller.rb
View file @
60ebd101
...
...
@@ -35,7 +35,7 @@ class Projects::BlobController < Projects::ApplicationController
end
def
show
@blob
.
override_max_size!
if
params
[
:override_max_size
]
==
'true'
override_max_blob_size
(
@blob
)
respond_to
do
|
format
|
format
.
html
do
...
...
app/controllers/projects/snippets_controller.rb
View file @
60ebd101
...
...
@@ -3,6 +3,7 @@ class Projects::SnippetsController < Projects::ApplicationController
include
ToggleAwardEmoji
include
SpammableActions
include
SnippetsActions
include
RendersBlob
before_action
:module_enabled
before_action
:snippet
,
only:
[
:show
,
:edit
,
:destroy
,
:update
,
:raw
,
:toggle_award_emoji
,
:mark_as_spam
]
...
...
@@ -55,11 +56,23 @@ class Projects::SnippetsController < Projects::ApplicationController
end
def
show
@note
=
@project
.
notes
.
new
(
noteable:
@snippet
)
@noteable
=
@snippet
@discussions
=
@snippet
.
discussions
@notes
=
prepare_notes_for_rendering
(
@discussions
.
flat_map
(
&
:notes
))
blob
=
@snippet
.
blob
override_max_blob_size
(
blob
)
respond_to
do
|
format
|
format
.
html
do
@note
=
@project
.
notes
.
new
(
noteable:
@snippet
)
@noteable
=
@snippet
@discussions
=
@snippet
.
discussions
@notes
=
prepare_notes_for_rendering
(
@discussions
.
flat_map
(
&
:notes
))
render
'show'
end
format
.
json
do
render_blob_json
(
blob
)
end
end
end
def
destroy
...
...
app/controllers/snippets_controller.rb
View file @
60ebd101
...
...
@@ -3,6 +3,7 @@ class SnippetsController < ApplicationController
include
SpammableActions
include
SnippetsActions
include
MarkdownPreview
include
RendersBlob
before_action
:snippet
,
only:
[
:show
,
:edit
,
:destroy
,
:update
,
:raw
,
:download
]
...
...
@@ -60,6 +61,18 @@ class SnippetsController < ApplicationController
end
def
show
blob
=
@snippet
.
blob
override_max_blob_size
(
blob
)
respond_to
do
|
format
|
format
.
html
do
render
'show'
end
format
.
json
do
render_blob_json
(
blob
)
end
end
end
def
destroy
...
...
app/helpers/blob_helper.rb
View file @
60ebd101
...
...
@@ -119,7 +119,15 @@ module BlobHelper
end
def
blob_raw_url
namespace_project_raw_path
(
@project
.
namespace
,
@project
,
@id
)
if
@snippet
if
@snippet
.
project_id
raw_namespace_project_snippet_path
(
@project
.
namespace
,
@project
,
@snippet
)
else
raw_snippet_path
(
@snippet
)
end
elsif
@blob
namespace_project_raw_path
(
@project
.
namespace
,
@project
,
@id
)
end
end
# SVGs can contain malicious JavaScript; only include whitelisted
...
...
@@ -212,8 +220,8 @@ module BlobHelper
clipboard_button
(
target:
".blob-content[data-blob-id='
#{
blob
.
id
}
']"
,
class:
"btn btn-sm js-copy-blob-source-btn"
,
title:
"Copy source to clipboard"
)
end
def
open_raw_
file_button
(
path
)
link_to
icon
(
'file-code-o'
),
path
,
class:
'btn btn-sm has-tooltip'
,
target:
'_blank'
,
rel:
'noopener noreferrer'
,
title:
'Open raw'
,
data:
{
container:
'body'
}
def
open_raw_
blob_button
link_to
icon
(
'file-code-o'
),
blob_raw_url
,
class:
'btn btn-sm has-tooltip'
,
target:
'_blank'
,
rel:
'noopener noreferrer'
,
title:
'Open raw'
,
data:
{
container:
'body'
}
end
def
blob_render_error_reason
(
viewer
)
...
...
app/models/snippet.rb
View file @
60ebd101
class
Snippet
<
ActiveRecord
::
Base
include
Gitlab
::
VisibilityLevel
include
Linguist
::
BlobHelper
include
CacheMarkdownField
include
Noteable
include
Participable
...
...
@@ -87,47 +86,26 @@ class Snippet < ActiveRecord::Base
]
end
def
data
content
def
blob
@blob
||=
Blob
.
decorate
(
SnippetBlob
.
new
(
self
),
nil
)
end
def
hook_attrs
attributes
end
def
size
0
end
def
file_name
super
.
to_s
end
# alias for compatibility with blobs and highlighting
def
path
file_name
end
def
name
file_name
end
def
sanitized_file_name
file_name
.
gsub
(
/[^a-zA-Z0-9_\-\.]+/
,
''
)
end
def
mode
nil
end
def
visibility_level_field
:visibility_level
end
def
no_highlighting?
content
.
lines
.
count
>
1000
end
def
notes_with_associations
notes
.
includes
(
:author
)
end
...
...
app/models/snippet_blob.rb
0 → 100644
View file @
60ebd101
class
SnippetBlob
include
Linguist
::
BlobHelper
attr_reader
:snippet
def
initialize
(
snippet
)
@snippet
=
snippet
end
delegate
:id
,
to: :snippet
def
name
snippet
.
file_name
end
alias_method
:path
,
:name
def
size
data
.
bytesize
end
def
data
snippet
.
content
end
def
rendered_markup
return
unless
Gitlab
::
MarkupHelper
.
gitlab_markdown?
(
name
)
Banzai
.
render_field
(
snippet
,
:content
)
end
def
mode
nil
end
def
binary?
false
end
def
load_all_data!
(
repository
)
# No-op
end
def
lfs_pointer?
false
end
def
lfs_oid
nil
end
def
lfs_size
nil
end
def
truncated?
false
end
end
app/views/projects/blob/_header.html.haml
View file @
60ebd101
...
...
@@ -16,7 +16,7 @@
.btn-group
{
role:
"group"
}
<
=
copy_blob_source_button
(
blob
)
if
!
blame
&&
blob
.
rendered_as_text?
(
ignore_errors:
false
)
=
open_raw_
file_button
(
namespace_project_raw_path
(
@project
.
namespace
,
@project
,
@id
))
=
open_raw_
blob_button
=
view_on_environment_button
(
@commit
.
sha
,
@path
,
@environment
)
if
@environment
.btn-group
{
role:
"group"
}
<
...
...
app/views/projects/blob/viewers/_markup.html.haml
View file @
60ebd101
-
blob
=
viewer
.
blob
-
rendered_markup
=
blob
.
rendered_markup
if
blob
.
respond_to?
(
:rendered_markup
)
.file-content.wiki
=
markup
(
blob
.
name
,
blob
.
data
)
=
markup
(
blob
.
name
,
blob
.
data
,
rendered:
rendered_markup
)
app/views/projects/snippets/show.html.haml
View file @
60ebd101
...
...
@@ -4,7 +4,7 @@
.project-snippets
%article
.file-holder.snippet-file-content
=
render
'shared/snippets/blob'
,
raw_path:
raw_namespace_project_snippet_path
(
@project
.
namespace
,
@project
,
@snippet
)
=
render
'shared/snippets/blob'
.row-content-block.top-block.content-component-block
=
render
'award_emoji/awards_block'
,
awardable:
@snippet
,
inline:
true
...
...
app/views/search/results/_snippet_blob.html.haml
View file @
60ebd101
...
...
@@ -39,7 +39,7 @@
.blob-content
-
snippet_chunks
.
each
do
|
chunk
|
-
unless
chunk
[
:data
].
empty?
=
highlight
(
snippet
.
file_name
,
chunk
[
:data
],
repository:
nil
,
plain:
snippet
.
no_highlighting?
)
=
highlight
(
snippet
.
file_name
,
chunk
[
:data
],
repository:
nil
,
plain:
snippet
.
blob
.
no_highlighting?
)
-
else
.file-content.code
.nothing-here-block
Empty file
app/views/shared/snippets/_blob.html.haml
View file @
60ebd101
-
blob
=
@snippet
.
blob
.js-file-title.file-title-flex-parent
.file-header-content
=
blob_icon
@snippet
.
mode
,
@snippet
.
path
=
blob_icon
blob
.
mode
,
blob
.
path
%strong
.file-title-name
=
@snippet
.
path
=
blob
.
path
=
copy_file_path_button
(
@snippet
.
path
)
=
copy_file_path_button
(
blob
.
path
)
%small
=
number_to_human_size
(
blob
.
raw_size
)
.file-actions.hidden-xs
=
render
'projects/blob/viewer_switcher'
,
blob:
blob
.btn-group
{
role:
"group"
}
<
=
copy_blob_source_button
(
@snippet
)
=
open_raw_
file_button
(
raw_path
)
=
copy_blob_source_button
(
blob
)
=
open_raw_
blob_button
-
if
defined?
(
download_path
)
&&
download_path
=
link_to
icon
(
'download'
),
download_path
,
class:
"btn btn-sm has-tooltip"
,
title:
'Download'
,
data:
{
container:
'body'
}
-
if
@snippet
.
content
.
empty?
.file-content.code
.nothing-here-block
Empty
file
-
else
-
if
markup?
(
@snippet
.
file_name
)
.file-content.wiki
-
if
gitlab_markdown?
(
@snippet
.
file_name
)
=
preserve
(
markdown_field
(
@snippet
,
:content
))
-
else
=
markup
(
@snippet
.
file_name
,
@snippet
.
content
)
-
else
=
render
'shared/file_highlight'
,
blob:
@snippet
=
render
'projects/blob/content'
,
blob:
blob
app/views/snippets/show.html.haml
View file @
60ebd101
...
...
@@ -3,7 +3,7 @@
=
render
'shared/snippets/header'
%article
.file-holder.snippet-file-content
=
render
'shared/snippets/blob'
,
raw_path:
raw_snippet_path
(
@snippet
),
download_path:
download_snippet_path
(
@snippet
)
=
render
'shared/snippets/blob'
,
download_path:
download_snippet_path
(
@snippet
)
.row-content-block.top-block.content-component-block
=
render
'award_emoji/awards_block'
,
awardable:
@snippet
,
inline:
true
features/project/snippets.feature
View file @
60ebd101
...
...
@@ -11,6 +11,7 @@ Feature: Project Snippets
Then
I should see
"Snippet one"
in snippets
And
I should not see
"Snippet two"
in snippets
@javascript
Scenario
:
I
create new project snippet
Given
I click link
"New snippet"
And
I submit new snippet
"Snippet three"
...
...
features/snippets/snippets.feature
View file @
60ebd101
...
...
@@ -5,6 +5,7 @@ Feature: Snippets
And
I have public
"Personal snippet one"
snippet
And
I have private
"Personal snippet private"
snippet
@javascript
Scenario
:
I
create new snippet
Given
I visit new snippet page
And
I submit new snippet
"Personal snippet three"
...
...
features/steps/project/snippets.rb
View file @
60ebd101
...
...
@@ -3,6 +3,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps
include
SharedProject
include
SharedNote
include
SharedPaths
include
WaitForAjax
step
'project "Shop" have "Snippet one" snippet'
do
create
(
:project_snippet
,
...
...
@@ -55,9 +56,10 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps
fill_in
"project_snippet_title"
,
with:
"Snippet three"
fill_in
"project_snippet_file_name"
,
with:
"my_snippet.rb"
page
.
within
(
'.file-editor'
)
do
find
(
:xpath
,
"//input[@id='project_snippet_content']"
).
set
'Content of snippet three'
find
(
'.ace_editor'
).
native
.
send_keys
'Content of snippet three'
end
click_button
"Create snippet"
wait_for_ajax
end
step
'I should see snippet "Snippet three"'
do
...
...
@@ -79,6 +81,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps
fill_in
"note_note"
,
with:
"Good snippet!"
click_button
"Comment"
end
wait_for_ajax
end
step
'I should see comment "Good snippet!"'
do
...
...
features/steps/snippets/snippets.rb
View file @
60ebd101
...
...
@@ -3,6 +3,7 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps
include
SharedPaths
include
SharedProject
include
SharedSnippet
include
WaitForAjax
step
'I click link "Personal snippet one"'
do
click_link
"Personal snippet one"
...
...
@@ -26,9 +27,10 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps
fill_in
"personal_snippet_title"
,
with:
"Personal snippet three"
fill_in
"personal_snippet_file_name"
,
with:
"my_snippet.rb"
page
.
within
(
'.file-editor'
)
do
find
(
:xpath
,
"//input[@id='personal_snippet_content']"
).
set
'Content of snippet three'
find
(
'.ace_editor'
).
native
.
send_keys
'Content of snippet three'
end
click_button
"Create snippet"
wait_for_ajax
end
step
'I submit new internal snippet'
do
...
...
spec/features/projects/blobs/blob_show_spec.rb
View file @
60ebd101
require
'spec_helper'
feature
'File blob'
,
:js
,
feature:
true
do
include
TreeHelper
include
WaitForAjax
let
(
:project
)
{
create
(
:project
,
:public
)
}
def
visit_blob
(
path
,
fragment
=
nil
)
visit
namespace_project_blob_path
(
project
.
namespace
,
project
,
tree_
join
(
'master'
,
path
),
anchor:
fragment
)
visit
namespace_project_blob_path
(
project
.
namespace
,
project
,
File
.
join
(
'master'
,
path
),
anchor:
fragment
)
end
context
'Ruby file'
do
...
...
@@ -39,7 +36,7 @@ feature 'File blob', :js, feature: true do
wait_for_ajax
end
it
'displays the blob'
do
it
'displays the blob
using the rich viewer
'
do
aggregate_failures
do
# hides the simple viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
,
visible:
false
)
...
...
@@ -63,7 +60,7 @@ feature 'File blob', :js, feature: true do
wait_for_ajax
end
it
'displays the blob'
do
it
'displays the blob
using the simple viewer
'
do
aggregate_failures
do
# hides the rich viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
)
...
...
@@ -84,7 +81,7 @@ feature 'File blob', :js, feature: true do
wait_for_ajax
end
it
'displays the blob'
do
it
'displays the blob
using the rich viewer
'
do
aggregate_failures
do
# hides the simple viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
,
visible:
false
)
...
...
@@ -105,7 +102,7 @@ feature 'File blob', :js, feature: true do
wait_for_ajax
end
it
'displays the blob'
do
it
'displays the blob
using the simple viewer
'
do
aggregate_failures
do
# hides the rich viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
)
...
...
spec/features/projects/snippets/show_spec.rb
0 → 100644
View file @
60ebd101
require
'spec_helper'
feature
'Project snippet'
,
:js
,
feature:
true
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project
,
file_name:
file_name
,
content:
content
)
}
before
do
project
.
team
<<
[
user
,
:master
]
login_as
(
user
)
end
context
'Ruby file'
do
let
(
:file_name
)
{
'popen.rb'
}
let
(
:content
)
{
project
.
repository
.
blob_at
(
'master'
,
'files/ruby/popen.rb'
).
data
}
before
do
visit
namespace_project_snippet_path
(
project
.
namespace
,
project
,
snippet
)
wait_for_ajax
end
it
'displays the blob'
do
aggregate_failures
do
# shows highlighted Ruby code
expect
(
page
).
to
have_content
(
"require 'fileutils'"
)
# does not show a viewer switcher
expect
(
page
).
not_to
have_selector
(
'.js-blob-viewer-switcher'
)
# shows an enabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn:not(.disabled)'
)
end
end
end
context
'Markdown file'
do
let
(
:file_name
)
{
'ruby-style-guide.md'
}
let
(
:content
)
{
project
.
repository
.
blob_at
(
'master'
,
'files/markdown/ruby-style-guide.md'
).
data
}
context
'visiting directly'
do
before
do
visit
namespace_project_snippet_path
(
project
.
namespace
,
project
,
snippet
)
wait_for_ajax
end
it
'displays the blob using the rich viewer'
do
aggregate_failures
do
# hides the simple viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
,
visible:
false
)
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="rich"]'
)
# shows rendered Markdown
expect
(
page
).
to
have_link
(
"PEP-8"
)
# shows a viewer switcher
expect
(
page
).
to
have_selector
(
'.js-blob-viewer-switcher'
)
# shows a disabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn.disabled'
)
end
end
context
'switching to the simple viewer'
do
before
do
find
(
'.js-blob-viewer-switch-btn[data-viewer=simple]'
).
click
wait_for_ajax
end
it
'displays the blob using the simple viewer'
do
aggregate_failures
do
# hides the rich viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
)
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="rich"]'
,
visible:
false
)
# shows highlighted Markdown code
expect
(
page
).
to
have_content
(
"[PEP-8](http://www.python.org/dev/peps/pep-0008/)"
)
# shows an enabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn:not(.disabled)'
)
end
end
context
'switching to the rich viewer again'
do
before
do
find
(
'.js-blob-viewer-switch-btn[data-viewer=rich]'
).
click
wait_for_ajax
end
it
'displays the blob using the rich viewer'
do
aggregate_failures
do
# hides the simple viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
,
visible:
false
)
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="rich"]'
)
# shows an enabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn:not(.disabled)'
)
end
end
end
end
end
context
'visiting with a line number anchor'
do
before
do
visit
namespace_project_snippet_path
(
project
.
namespace
,
project
,
snippet
,
anchor:
'L1'
)
wait_for_ajax
end
it
'displays the blob using the simple viewer'
do
aggregate_failures
do
# hides the rich viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
)
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="rich"]'
,
visible:
false
)
# highlights the line in question
expect
(
page
).
to
have_selector
(
'#LC1.hll'
)
# shows highlighted Markdown code
expect
(
page
).
to
have_content
(
"[PEP-8](http://www.python.org/dev/peps/pep-0008/)"
)
# shows an enabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn:not(.disabled)'
)
end
end
end
end
end
spec/features/snippets/create_snippet_spec.rb
View file @
60ebd101
require
'rails_helper'
feature
'Create Snippet'
,
feature:
true
do
feature
'Create Snippet'
,
:js
,
feature:
true
do
before
do
login_as
:user
visit
new_snippet_path
...
...
@@ -9,10 +9,11 @@ feature 'Create Snippet', feature: true do
scenario
'Authenticated user creates a snippet'
do
fill_in
'personal_snippet_title'
,
with:
'My Snippet Title'
page
.
within
(
'.file-editor'
)
do
find
(
:xpath
,
"//input[@id='personal_snippet_content']"
).
set
'Hello World!'
find
(
'.ace_editor'
).
native
.
send_keys
'Hello World!'
end
click_button
'Create snippet'
wait_for_ajax
expect
(
page
).
to
have_content
(
'My Snippet Title'
)
expect
(
page
).
to
have_content
(
'Hello World!'
)
...
...
@@ -22,10 +23,11 @@ feature 'Create Snippet', feature: true do
fill_in
'personal_snippet_title'
,
with:
'My Snippet Title'
page
.
within
(
'.file-editor'
)
do
find
(
:xpath
,
"//input[@id='personal_snippet_file_name']"
).
set
'snippet+file+name'
find
(
:xpath
,
"//input[@id='personal_snippet_content']"
).
set
'Hello World!'
find
(
'.ace_editor'
).
native
.
send_keys
'Hello World!'
end
click_button
'Create snippet'
wait_for_ajax
expect
(
page
).
to
have_content
(
'My Snippet Title'
)
expect
(
page
).
to
have_content
(
'snippet+file+name'
)
...
...
spec/features/snippets/public_snippets_spec.rb
View file @
60ebd101
require
'rails_helper'
feature
'Public Snippets'
,
feature:
true
do
feature
'Public Snippets'
,
:js
,
feature:
true
do
scenario
'Unauthenticated user should see public snippets'
do
public_snippet
=
create
(
:personal_snippet
,
:public
)
visit
snippet_path
(
public_snippet
)
wait_for_ajax
expect
(
page
).
to
have_content
(
public_snippet
.
content
)
end
...
...
spec/features/snippets/show_spec.rb
0 → 100644
View file @
60ebd101
require
'spec_helper'
feature
'Snippet'
,
:js
,
feature:
true
do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:snippet
)
{
create
(
:personal_snippet
,
:public
,
file_name:
file_name
,
content:
content
)
}
context
'Ruby file'
do
let
(
:file_name
)
{
'popen.rb'
}
let
(
:content
)
{
project
.
repository
.
blob_at
(
'master'
,
'files/ruby/popen.rb'
).
data
}
before
do
visit
snippet_path
(
snippet
)
wait_for_ajax
end
it
'displays the blob'
do
aggregate_failures
do
# shows highlighted Ruby code
expect
(
page
).
to
have_content
(
"require 'fileutils'"
)
# does not show a viewer switcher
expect
(
page
).
not_to
have_selector
(
'.js-blob-viewer-switcher'
)
# shows an enabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn:not(.disabled)'
)
end
end
end
context
'Markdown file'
do
let
(
:file_name
)
{
'ruby-style-guide.md'
}
let
(
:content
)
{
project
.
repository
.
blob_at
(
'master'
,
'files/markdown/ruby-style-guide.md'
).
data
}
context
'visiting directly'
do
before
do
visit
snippet_path
(
snippet
)
wait_for_ajax
end
it
'displays the blob using the rich viewer'
do
aggregate_failures
do
# hides the simple viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
,
visible:
false
)
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="rich"]'
)
# shows rendered Markdown
expect
(
page
).
to
have_link
(
"PEP-8"
)
# shows a viewer switcher
expect
(
page
).
to
have_selector
(
'.js-blob-viewer-switcher'
)
# shows a disabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn.disabled'
)
end
end
context
'switching to the simple viewer'
do
before
do
find
(
'.js-blob-viewer-switch-btn[data-viewer=simple]'
).
click
wait_for_ajax
end
it
'displays the blob using the simple viewer'
do
aggregate_failures
do
# hides the rich viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
)
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="rich"]'
,
visible:
false
)
# shows highlighted Markdown code
expect
(
page
).
to
have_content
(
"[PEP-8](http://www.python.org/dev/peps/pep-0008/)"
)
# shows an enabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn:not(.disabled)'
)
end
end
context
'switching to the rich viewer again'
do
before
do
find
(
'.js-blob-viewer-switch-btn[data-viewer=rich]'
).
click
wait_for_ajax
end
it
'displays the blob using the rich viewer'
do
aggregate_failures
do
# hides the simple viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
,
visible:
false
)
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="rich"]'
)
# shows an enabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn:not(.disabled)'
)
end
end
end
end
end
context
'visiting with a line number anchor'
do
before
do
visit
snippet_path
(
snippet
,
anchor:
'L1'
)
wait_for_ajax
end
it
'displays the blob using the simple viewer'
do
aggregate_failures
do
# hides the rich viewer
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="simple"]'
)
expect
(
page
).
to
have_selector
(
'.blob-viewer[data-type="rich"]'
,
visible:
false
)
# highlights the line in question
expect
(
page
).
to
have_selector
(
'#LC1.hll'
)
# shows highlighted Markdown code
expect
(
page
).
to
have_content
(
"[PEP-8](http://www.python.org/dev/peps/pep-0008/)"
)
# shows an enabled copy button
expect
(
page
).
to
have_selector
(
'.js-copy-blob-source-btn:not(.disabled)'
)
end
end
end
end
end
spec/helpers/blob_helper_spec.rb
View file @
60ebd101
...
...
@@ -157,6 +157,7 @@ describe BlobHelper do
describe
'#blob_render_error_options'
do
before
do
assign
(
:project
,
project
)
assign
(
:blob
,
blob
)
assign
(
:id
,
File
.
join
(
'master'
,
blob
.
path
))
controller
.
params
[
:controller
]
=
'projects/blob'
...
...
spec/javascripts/fixtures/line_highlighter.html.haml
View file @
60ebd101
#blob-content
-holder
.file
-holder
.file-content
.line-numbers
-
1
.
upto
(
25
)
do
|
i
|
...
...
spec/models/snippet_blob_spec.rb
0 → 100644
View file @
60ebd101
require
'spec_helper'
describe
SnippetBlob
,
models:
true
do
let
(
:snippet
)
{
create
(
:snippet
)
}
subject
{
described_class
.
new
(
snippet
)
}
describe
'#id'
do
it
'returns the snippet ID'
do
expect
(
subject
.
id
).
to
eq
(
snippet
.
id
)
end
end
describe
'#name'
do
it
'returns the snippet file name'
do
expect
(
subject
.
name
).
to
eq
(
snippet
.
file_name
)
end
end
describe
'#size'
do
it
'returns the data size'
do
expect
(
subject
.
size
).
to
eq
(
subject
.
data
.
bytesize
)
end
end
describe
'#data'
do
it
'returns the snippet content'
do
expect
(
subject
.
data
).
to
eq
(
snippet
.
content
)
end
end
describe
'#rendered_markup'
do
context
'when the content is GFM'
do
let
(
:snippet
)
{
create
(
:snippet
,
file_name:
'file.md'
)
}
it
'returns the rendered GFM'
do
expect
(
subject
.
rendered_markup
).
to
eq
(
snippet
.
content_html
)
end
end
context
'when the content is not GFM'
do
it
'returns nil'
do
expect
(
subject
.
rendered_markup
).
to
be_nil
end
end
end
end
spec/models/snippet_spec.rb
View file @
60ebd101
...
...
@@ -5,7 +5,6 @@ describe Snippet, models: true do
subject
{
described_class
}
it
{
is_expected
.
to
include_module
(
Gitlab
::
VisibilityLevel
)
}
it
{
is_expected
.
to
include_module
(
Linguist
::
BlobHelper
)
}
it
{
is_expected
.
to
include_module
(
Participable
)
}
it
{
is_expected
.
to
include_module
(
Referable
)
}
it
{
is_expected
.
to
include_module
(
Sortable
)
}
...
...
@@ -241,4 +240,16 @@ describe Snippet, models: true do
end
end
end
describe
'#blob'
do
let
(
:snippet
)
{
create
(
:snippet
)
}
it
'returns a blob representing the snippet data'
do
blob
=
snippet
.
blob
expect
(
blob
).
to
be_a
(
Blob
)
expect
(
blob
.
path
).
to
eq
(
snippet
.
file_name
)
expect
(
blob
.
data
).
to
eq
(
snippet
.
content
)
end
end
end
spec/views/projects/blob/_viewer.html.haml_spec.rb
View file @
60ebd101
...
...
@@ -21,6 +21,7 @@ describe 'projects/blob/_viewer.html.haml', :view do
before
do
assign
(
:project
,
project
)
assign
(
:blob
,
blob
)
assign
(
:id
,
File
.
join
(
'master'
,
blob
.
path
))
controller
.
params
[
:controller
]
=
'projects/blob'
...
...
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