summaryrefslogtreecommitdiff
path: root/spec/features/copy_as_gfm_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/features/copy_as_gfm_spec.rb')
-rw-r--r--spec/features/copy_as_gfm_spec.rb234
1 files changed, 234 insertions, 0 deletions
diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb
new file mode 100644
index 00000000000..8e8c0ecb282
--- /dev/null
+++ b/spec/features/copy_as_gfm_spec.rb
@@ -0,0 +1,234 @@
+require 'spec_helper'
+
+describe 'Copy as GFM', feature: true, js: true do
+ include GitlabMarkdownHelper
+ include ActionView::Helpers::JavaScriptHelper
+
+ before do
+ @feat = MarkdownFeature.new
+
+ # `markdown` helper expects a `@project` variable
+ @project = @feat.project
+
+ 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
+
+ [![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
+
+ 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
+
+ - Perform code reviews and enhance collaboration with merge requests
+
+ - 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
+
+ - 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' => [
+ '{-Deleted text-}',
+ '{+Added text+}'
+ ],
+ 'TaskListFilter' => [
+ '- [ ] 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' => [
+ '$`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' => [
+ '`code`',
+ '`` code with ` ticks ``',
+
+ '> Quote',
+ [
+ 'multiline quote',
+ <<-GFM.strip_heredoc,
+ > Multiline
+ > Quote
+ >
+ > With multiple paragraphs
+ GFM
+ ],
+
+ '![Image](https://example.com/image.png)',
+
+ '# Heading with no anchor link',
+
+ '[Link](https://example.com)',
+
+ '- List item',
+ [
+ '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
+ ],
+
+ '# Heading',
+ '## Heading',
+ '### Heading',
+ '#### Heading',
+ '##### Heading',
+ '###### Heading',
+
+ '**Bold**',
+
+ '_Italics_',
+
+ '~~Strikethrough~~',
+
+ '2^2',
+
+ '-----',
+
+ [
+ '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
+ end
+
+ def html_to_gfm(html)
+ js = <<-JS.strip_heredoc
+ (function(html) {
+ var node = document.createElement('div');
+ node.innerHTML = html;
+ return window.gl.CopyAsGFM.nodeToGFM(node);
+ })("#{escape_javascript(html)}")
+ JS
+ page.evaluate_script(js)
+ end
+
+ # Fake a `current_user` helper
+ def current_user
+ @feat.user
+ end
+end