Improve spec
This commit is contained in:
parent
37cabebe16
commit
bc3448fc48
3 changed files with 159 additions and 153 deletions
|
@ -3,9 +3,10 @@
|
|||
|
||||
(() => {
|
||||
const gfmRules = {
|
||||
// Should have an entry for every filter in lib/banzai/pipeline/gfm_pipeline.rb,
|
||||
// in reverse order.
|
||||
// Should have test coverage in spec/features/copy_as_gfm_spec.rb.
|
||||
// The filters referenced in lib/banzai/pipeline/gfm_pipeline.rb convert GitLab Flavored Markdown (GFM) to HTML.
|
||||
// These handlers consequently convert that same HTML to GFM to be copied to the clipboard.
|
||||
// Every filter in lib/banzai/pipeline/gfm_pipeline.rb that generates HTML from GFM should have a handler here, in reverse order.
|
||||
// The GFM-to-HTML-to-GFM cycle is tested in spec/features/copy_as_gfm_spec.rb.
|
||||
InlineDiffFilter: {
|
||||
'span.idiff.addition'(el, text) {
|
||||
return `{+${text}+}`;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
module Banzai
|
||||
module Pipeline
|
||||
class GfmPipeline < BasePipeline
|
||||
# Every filter should have an entry in app/assets/javascripts/copy_as_gfm.js.es6,
|
||||
# in reverse order.
|
||||
# Should have test coverage in spec/features/copy_as_gfm_spec.rb.
|
||||
# These filters convert GitLab Flavored Markdown (GFM) to HTML.
|
||||
# The handlers defined in app/assets/javascripts/copy_as_gfm.js.es6 consequently convert that same HTML to GFM to be copied to the clipboard.
|
||||
# Every filter that generates HTML from GFM should have a handler in app/assets/javascripts/copy_as_gfm.js.es6, in reverse order.
|
||||
# The GFM-to-HTML-to-GFM cycle is tested in spec/features/copy_as_gfm_spec.rb.
|
||||
def self.filters
|
||||
@filters ||= FilterArray[
|
||||
Filter::SyntaxHighlightFilter,
|
||||
|
|
|
@ -13,117 +13,135 @@ describe 'Copy as GFM', feature: true, js: true do
|
|||
visit namespace_project_issue_path(@project.namespace, @project, @feat.issue)
|
||||
end
|
||||
|
||||
# Should have an entry for every filter in lib/banzai/pipeline/gfm_pipeline.rb
|
||||
# and app/assets/javascripts/copy_as_gfm.js.es6
|
||||
filters = {
|
||||
'any filter' => [
|
||||
[
|
||||
'crazy nesting',
|
||||
'> 1. [x] **[$`2 + 2`$ {-=-}{+=+} 2^2 ~~:thumbsup:~~](http://google.com)**'
|
||||
],
|
||||
[
|
||||
'real world example from the gitlab-ce README',
|
||||
<<-GFM.strip_heredoc
|
||||
# GitLab
|
||||
# The filters referenced in lib/banzai/pipeline/gfm_pipeline.rb convert GitLab Flavored Markdown (GFM) to HTML.
|
||||
# The handlers defined in app/assets/javascripts/copy_as_gfm.js.es6 consequently convert that same HTML to GFM.
|
||||
# To make sure these filters and handlers are properly aligned, this spec tests the GFM-to-HTML-to-GFM cycle
|
||||
# by verifying (`html_to_gfm(gfm_to_html(gfm)) == gfm`) for a number of examples of GFM for every filter.
|
||||
|
||||
[![Build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master)
|
||||
[![CE coverage report](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage)](https://gitlab-org.gitlab.io/gitlab-ce/coverage-ruby)
|
||||
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
[![Core Infrastructure Initiative Best Practices](https://bestpractices.coreinfrastructure.org/projects/42/badge)](https://bestpractices.coreinfrastructure.org/projects/42)
|
||||
it 'supports nesting' do
|
||||
verify '> 1. [x] **[$`2 + 2`$ {-=-}{+=+} 2^2 ~~:thumbsup:~~](http://google.com)**'
|
||||
end
|
||||
|
||||
## Canonical source
|
||||
it 'supports a real world example from the gitlab-ce README' do
|
||||
verify <<-GFM.strip_heredoc
|
||||
# GitLab
|
||||
|
||||
The canonical source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/).
|
||||
[![Build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master)
|
||||
[![CE coverage report](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage)](https://gitlab-org.gitlab.io/gitlab-ce/coverage-ruby)
|
||||
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
[![Core Infrastructure Initiative Best Practices](https://bestpractices.coreinfrastructure.org/projects/42/badge)](https://bestpractices.coreinfrastructure.org/projects/42)
|
||||
|
||||
## Open source software to collaborate on code
|
||||
## Canonical source
|
||||
|
||||
To see how GitLab looks please see the [features page on our website](https://about.gitlab.com/features/).
|
||||
The canonical source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/).
|
||||
|
||||
## Open source software to collaborate on code
|
||||
|
||||
To see how GitLab looks please see the [features page on our website](https://about.gitlab.com/features/).
|
||||
|
||||
|
||||
- Manage Git repositories with fine grained access controls that keep your code secure
|
||||
- Manage Git repositories with fine grained access controls that keep your code secure
|
||||
|
||||
- Perform code reviews and enhance collaboration with merge requests
|
||||
- Perform code reviews and enhance collaboration with merge requests
|
||||
|
||||
- Complete continuous integration (CI) and CD pipelines to builds, test, and deploy your applications
|
||||
- Complete continuous integration (CI) and CD pipelines to builds, test, and deploy your applications
|
||||
|
||||
- Each project can also have an issue tracker, issue board, and a wiki
|
||||
- Each project can also have an issue tracker, issue board, and a wiki
|
||||
|
||||
- Used by more than 100,000 organizations, GitLab is the most popular solution to manage Git repositories on-premises
|
||||
- Used by more than 100,000 organizations, GitLab is the most popular solution to manage Git repositories on-premises
|
||||
|
||||
- Completely free and open source (MIT Expat license)
|
||||
GFM
|
||||
]
|
||||
],
|
||||
'InlineDiffFilter' => [
|
||||
- Completely free and open source (MIT Expat license)
|
||||
GFM
|
||||
end
|
||||
|
||||
it 'supports InlineDiffFilter' do
|
||||
verify(
|
||||
'{-Deleted text-}',
|
||||
'{+Added text+}'
|
||||
],
|
||||
'TaskListFilter' => [
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports TaskListFilter' do
|
||||
verify(
|
||||
'- [ ] Unchecked task',
|
||||
'- [x] Checked task',
|
||||
'1. [ ] Unchecked numbered task',
|
||||
'1. [x] Checked numbered task'
|
||||
],
|
||||
'ReferenceFilter' => [
|
||||
['issue reference', -> { @feat.issue.to_reference }],
|
||||
['full issue reference', -> { @feat.issue.to_reference(full: true) }],
|
||||
['issue URL', -> { namespace_project_issue_url(@project.namespace, @project, @feat.issue) }],
|
||||
['issue URL with note anchor', -> { namespace_project_issue_url(@project.namespace, @project, @feat.issue, anchor: 'note_123') }],
|
||||
['issue link', -> { "[Issue](#{namespace_project_issue_url(@project.namespace, @project, @feat.issue)})" }],
|
||||
['issue link with note anchor', -> { "[Issue](#{namespace_project_issue_url(@project.namespace, @project, @feat.issue, anchor: 'note_123')})" }],
|
||||
],
|
||||
'AutolinkFilter' => [
|
||||
'https://example.com'
|
||||
],
|
||||
'TableOfContentsFilter' => [
|
||||
'[[_TOC_]]'
|
||||
],
|
||||
'EmojiFilter' => [
|
||||
':thumbsup:'
|
||||
],
|
||||
'ImageLinkFilter' => [
|
||||
'![Image](https://example.com/image.png)'
|
||||
],
|
||||
'VideoLinkFilter' => [
|
||||
'![Video](https://example.com/video.mp4)'
|
||||
],
|
||||
'MathFilter' => [
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports ReferenceFilter' do
|
||||
verify(
|
||||
# issue reference
|
||||
@feat.issue.to_reference,
|
||||
# full issue reference
|
||||
@feat.issue.to_reference(full: true),
|
||||
# issue URL
|
||||
namespace_project_issue_url(@project.namespace, @project, @feat.issue),
|
||||
# issue URL with note anchor
|
||||
namespace_project_issue_url(@project.namespace, @project, @feat.issue, anchor: 'note_123'),
|
||||
# issue link
|
||||
"[Issue](#{namespace_project_issue_url(@project.namespace, @project, @feat.issue)})",
|
||||
# issue link with note anchor
|
||||
"[Issue](#{namespace_project_issue_url(@project.namespace, @project, @feat.issue, anchor: 'note_123')})",
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports AutolinkFilter' do
|
||||
verify 'https://example.com'
|
||||
end
|
||||
|
||||
it 'supports TableOfContentsFilter' do
|
||||
verify '[[_TOC_]]'
|
||||
end
|
||||
|
||||
it 'supports EmojiFilter' do
|
||||
verify ':thumbsup:'
|
||||
end
|
||||
|
||||
it 'supports ImageLinkFilter' do
|
||||
verify '![Image](https://example.com/image.png)'
|
||||
end
|
||||
|
||||
it 'supports VideoLinkFilter' do
|
||||
verify '![Video](https://example.com/video.mp4)'
|
||||
end
|
||||
|
||||
it 'supports MathFilter' do
|
||||
verify(
|
||||
'$`c = \pm\sqrt{a^2 + b^2}`$',
|
||||
[
|
||||
'math block',
|
||||
<<-GFM.strip_heredoc
|
||||
```math
|
||||
c = \pm\sqrt{a^2 + b^2}
|
||||
```
|
||||
GFM
|
||||
]
|
||||
],
|
||||
'SyntaxHighlightFilter' => [
|
||||
[
|
||||
'code block',
|
||||
<<-GFM.strip_heredoc
|
||||
```ruby
|
||||
def foo
|
||||
bar
|
||||
end
|
||||
```
|
||||
GFM
|
||||
]
|
||||
],
|
||||
'MarkdownFilter' => [
|
||||
# math block
|
||||
<<-GFM.strip_heredoc
|
||||
```math
|
||||
c = \pm\sqrt{a^2 + b^2}
|
||||
```
|
||||
GFM
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports SyntaxHighlightFilter' do
|
||||
verify <<-GFM.strip_heredoc
|
||||
```ruby
|
||||
def foo
|
||||
bar
|
||||
end
|
||||
```
|
||||
GFM
|
||||
end
|
||||
|
||||
it 'supports MarkdownFilter' do
|
||||
verify(
|
||||
'`code`',
|
||||
'`` code with ` ticks ``',
|
||||
|
||||
'> Quote',
|
||||
[
|
||||
'multiline quote',
|
||||
<<-GFM.strip_heredoc,
|
||||
> Multiline
|
||||
> Quote
|
||||
>
|
||||
> With multiple paragraphs
|
||||
GFM
|
||||
],
|
||||
# multiline quote
|
||||
<<-GFM.strip_heredoc,
|
||||
> Multiline
|
||||
> Quote
|
||||
>
|
||||
> With multiple paragraphs
|
||||
GFM
|
||||
|
||||
'![Image](https://example.com/image.png)',
|
||||
|
||||
|
@ -132,39 +150,36 @@ describe 'Copy as GFM', feature: true, js: true do
|
|||
'[Link](https://example.com)',
|
||||
|
||||
'- List item',
|
||||
[
|
||||
'multiline list item',
|
||||
<<-GFM.strip_heredoc,
|
||||
- Multiline
|
||||
List item
|
||||
GFM
|
||||
],
|
||||
[
|
||||
'nested lists',
|
||||
<<-GFM.strip_heredoc,
|
||||
- Nested
|
||||
|
||||
# multiline list item
|
||||
<<-GFM.strip_heredoc,
|
||||
- Multiline
|
||||
List item
|
||||
GFM
|
||||
|
||||
# nested lists
|
||||
<<-GFM.strip_heredoc,
|
||||
- Nested
|
||||
|
||||
|
||||
- Lists
|
||||
GFM
|
||||
],
|
||||
- Lists
|
||||
GFM
|
||||
|
||||
'1. Numbered list item',
|
||||
[
|
||||
'multiline numbered list item',
|
||||
<<-GFM.strip_heredoc,
|
||||
1. Multiline
|
||||
Numbered list item
|
||||
GFM
|
||||
],
|
||||
[
|
||||
'nested numbered list',
|
||||
<<-GFM.strip_heredoc,
|
||||
1. Nested
|
||||
|
||||
# multiline numbered list item
|
||||
<<-GFM.strip_heredoc,
|
||||
1. Multiline
|
||||
Numbered list item
|
||||
GFM
|
||||
|
||||
# nested numbered list
|
||||
<<-GFM.strip_heredoc,
|
||||
1. Nested
|
||||
|
||||
|
||||
1. Numbered lists
|
||||
GFM
|
||||
],
|
||||
1. Numbered lists
|
||||
GFM
|
||||
|
||||
'# Heading',
|
||||
'## Heading',
|
||||
|
@ -183,39 +198,18 @@ describe 'Copy as GFM', feature: true, js: true do
|
|||
|
||||
'-----',
|
||||
|
||||
[
|
||||
'table',
|
||||
<<-GFM.strip_heredoc,
|
||||
| Centered | Right | Left |
|
||||
| :------: | ----: | ---- |
|
||||
| Foo | Bar | **Baz** |
|
||||
| Foo | Bar | **Baz** |
|
||||
GFM
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
filters.each do |filter, examples|
|
||||
context filter do
|
||||
examples.each do |ex|
|
||||
if ex.is_a?(String)
|
||||
desc = "'#{ex}'"
|
||||
gfm = ex
|
||||
else
|
||||
desc, gfm = ex
|
||||
end
|
||||
|
||||
it "transforms #{desc} to HTML and back to GFM" do
|
||||
gfm = instance_exec(&gfm) if gfm.is_a?(Proc)
|
||||
|
||||
html = markdown(gfm)
|
||||
gfm2 = html_to_gfm(html)
|
||||
expect(gfm2.strip).to eq(gfm.strip)
|
||||
end
|
||||
end
|
||||
end
|
||||
# table
|
||||
<<-GFM.strip_heredoc,
|
||||
| Centered | Right | Left |
|
||||
| :------: | ----: | ---- |
|
||||
| Foo | Bar | **Baz** |
|
||||
| Foo | Bar | **Baz** |
|
||||
GFM
|
||||
)
|
||||
end
|
||||
|
||||
alias_method :gfm_to_html, :markdown
|
||||
|
||||
def html_to_gfm(html)
|
||||
js = <<-JS.strip_heredoc
|
||||
(function(html) {
|
||||
|
@ -227,6 +221,16 @@ describe 'Copy as GFM', feature: true, js: true do
|
|||
page.evaluate_script(js)
|
||||
end
|
||||
|
||||
def verify(*gfms)
|
||||
aggregate_failures do
|
||||
gfms.each do |gfm|
|
||||
html = gfm_to_html(gfm)
|
||||
output_gfm = html_to_gfm(html)
|
||||
expect(output_gfm.strip).to eq(gfm.strip)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Fake a `current_user` helper
|
||||
def current_user
|
||||
@feat.user
|
||||
|
|
Loading…
Reference in a new issue