summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@selenight.nl>2017-01-16 18:11:15 -0500
committerDouwe Maan <douwe@selenight.nl>2017-01-16 18:11:15 -0500
commitbc3448fc48a289342948ec155fa9c7f2d49ca2bd (patch)
tree13f96b866d4d285b16784b40a665802e41bb8c31
parent37cabebe1661ab09eec6dfb74b7b09bc03e5f454 (diff)
downloadgitlab-ce-bc3448fc48a289342948ec155fa9c7f2d49ca2bd.tar.gz
Improve spec
-rw-r--r--app/assets/javascripts/copy_as_gfm.js.es67
-rw-r--r--lib/banzai/pipeline/gfm_pipeline.rb7
-rw-r--r--spec/features/copy_as_gfm_spec.rb306
3 files changed, 163 insertions, 157 deletions
diff --git a/app/assets/javascripts/copy_as_gfm.js.es6 b/app/assets/javascripts/copy_as_gfm.js.es6
index f9098c7041c..7c666697cdf 100644
--- a/app/assets/javascripts/copy_as_gfm.js.es6
+++ b/app/assets/javascripts/copy_as_gfm.js.es6
@@ -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}+}`;
diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb
index 09038d38b1f..7b652aa79ec 100644
--- a/lib/banzai/pipeline/gfm_pipeline.rb
+++ b/lib/banzai/pipeline/gfm_pipeline.rb
@@ -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,
diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb
index 8e8c0ecb282..dd22f92c5c8 100644
--- a/spec/features/copy_as_gfm_spec.rb
+++ b/spec/features/copy_as_gfm_spec.rb
@@ -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
+
+ it 'supports a real world example from the gitlab-ce README' do
+ verify <<-GFM.strip_heredoc
+ # GitLab
+
+ [![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)
- ## Canonical source
+ ## Canonical source
- The canonical source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/).
+ 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
+ ## 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/).
+ 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
-
-
- - Lists
- GFM
- ],
+
+ # multiline list item
+ <<-GFM.strip_heredoc,
+ - Multiline
+ List item
+ GFM
+
+ # nested lists
+ <<-GFM.strip_heredoc,
+ - Nested
+
+
+ - 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
-
-
- 1. Numbered lists
- GFM
- ],
+
+ # 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
'# 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