# Related Specs: # # This data file drives the specs in the following specs: # # CE Backend: spec/requests/api/markdown_golden_master_spec.rb # CE Frontend: spec/frontend/content_editor/markdown_processing_spec.js # # For EE, these files are used: # EE Data: ee/spec/fixtures/markdown/markdown_golden_master_examples.yml # EE Backend: ee/spec/requests/api/markdown_golden_master_spec.rb # EE Frontend: ee/spec/frontend/content_editor/ee_markdown_processing_spec.js # # # Requirements: # # 1. Frontend: We should have test coverage that the Content Editor can properly serialize HTML # to Markdown for all GFM source elements which it currently supports. # 2. Frontend: We should have test coverage that the Content Editor can properly render the expected # HTML for all GFM source elements which it currently supports (not currently implemented in the # frontend - this will likely be a standalone module outside of the Content Editor). # 3. Backend: We should ensure that for all GFM elements, the backend always renders the expected # HTML, for **all** supported GFM source elements. # # If any of this this ever changes unexpectedly, tests will start failing, and force the same change # to be made on the backend and frontend. # # # Overview: # # These specs ensure that the bidirectional Markdown <-> HTML conversion logic is implemented # identically on the backend and frontend, for all supported GitLab-Flavored Markdown examples, by # running hardcoded examples through the logic and ensuring the results match. # # This is an example of the "Golden Master Testing" approach, which is also referred to as # "Approval Testing" or "Characterization Testing". # # The term "Golden Master" originally comes from the recording industry, and refers to process # of "mastering", or making a final mix from which all other copies will be produced. # # See: # - https://en.wikipedia.org/wiki/Characterization_test # - https://en.wikipedia.org/wiki/Gold_master_(disambiguation) # # # What we are doing is actually a type Golden Master testing with modifications: # # 1. The original markdown examples used to drive the tests are taken from this YAML, and can be # considered a form of "fixture" in this case. # 2. The HTML in the YAML is the "Golden Master", but we are going to use it to assert # against **TWO** different implementations of markdown rendering: # 1. The frontend, implemented as Jest specs. # 1. This will assert both HTML -> markdown serialization (what it currently does), as well as... # 2. Markdown -> HTML rendering (not currently implemented in the frontend - this will likely # be a standalone module outside of the Content Editor) # 1. The backend, implemented as requests specs # 1. This will assert markdown -> HTML conversion by the backend. # # Also see the MR for more explanation on the details of this approach: # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68671 # # # Usage: # # * Please keep this file alphabetized. # * To run focused example(s), set the `FOCUSED_MARKDOWN_EXAMPLES` environment variable to a # comma-separated list of example names. This works for the frontend and backend specs. # * Required attributes for every example: # 1. `name`: Specifies the Name of the example, which will be printed when specs are run. # 2. `markdown`: Specifies the Markdown for the example, which will be compared with the # Markdown the code generates from the corresponding specified HTML. # 3. `html`: Specifies the HTML for the example, which will be compared with the # HTML the code generated from the corresponding specified Markdown. # * `api_context` (optional): This is used when a single markdown can be # rendered differently depending on the API endpoint or area of the app from which it is called or # used. The valid values for `api_context` are: `project`, `group`, `project_wiki`, # and (for EE only) `group_wiki`.The `name` attribute must also have a `_for_[API_CONTEXT]` suffix # which matches the `api_context`, in order to ensure that each example has a unique `name` # identifier. For example, `attachment_image_for_project`. # * `pending`: To skip an example that is broken or not yet fully implemented, add # a `pending: ` attribute to the example. See # the `a_example_of_pending` entry for an example. # * `pending` with key: You can also mark an example pending on only the frontend or backend. See # the `a_example_of_pending_with_keys` entry for an example. # * `substitutions`: For examples which may have variable content in different environments, # such as portions of the URI, or database record IDs, you can specify # `substitutions`, which is an array of regex/replacement pairs. The HTML # value will be normalized with each of these pairs using Ruby `gsub` # before comparing. # The substitution values can (and are) also reused in multiple examples # via YAML anchors. # # # Notes: # # * The html values should exactly match what the backend markdown API endpoints return for the # given markdown example. The HTML is intentionally not indented, formatted, or split across lines. # This is a bit less readable, but it makes the spec logic simpler and less error prone for edge # cases. # # # Debugging Failures and Writing New Entries: # # * You need to compare what is different between the expected and actual values. # * In rspec, the diff printed out includes the full text of the HTML. This may be long, so you # may want to turn line wrapping on or off or copy the diff to separate file(s) for easier comparison. # * If the difference is just in an attribute value, use the `substitutions` support to normalize # the HTML before comparing. These specs are only validating the HTML structure, the individual # markdown elements' unit tests can provide coverage that the exact attribute values are correct. # * If you are making a new entry, you can create the entry according to the `Usage` section above, # but leave the `html` value blank. This will cause the spec to fail, and you can fill in the # `html` value based on the spec failure that is printed out. --- #- name: an_example_of_pending # pending: 'This is an example of the pending attribute: http://example.com' # markdown: ;) # html: |- # # #- name: an_example_of_pending_with_keys # pending: # frontend: 'This is an example of the frontend-only pending attribute: http://example.com' # backend: 'This is an example of the backend-only pending attribute: http://example.com' # markdown: ;) # html: |- # - name: attachment_image_for_group api_context: group substitutions: # Note: having the top level `substitutions` data structure be a hash of arrays # allows us to compose multiple substitutions via YAML anchors (YAML anchors # pointing to arrays can't be combined) uri_substitution: &uri_substitution # NOTE: We don't care about verifying specific attribute values here, that should be the # responsibility of unit tests. These tests are about the structure of the HTML. - regex: '(href|data-src)(=")(.*?)(test-file\.(png|zip)")' replacement: '\1\2URI_PREFIX\4' markdown: |- ![test-file](/uploads/aa45a38ec2cfe97433281b10bbff042c/test-file.png) html: |-

test-file

- name: attachment_image_for_project api_context: project substitutions: uri_substitution: *uri_substitution markdown: |- ![test-file](/uploads/aa45a38ec2cfe97433281b10bbff042c/test-file.png) html: |-

test-file

- name: attachment_image_for_project_wiki api_context: project_wiki substitutions: uri_substitution: *uri_substitution markdown: |- ![test-file](test-file.png) html: |-

test-file

- name: attachment_link_for_group api_context: group substitutions: uri_substitution: *uri_substitution markdown: |- [test-file](/uploads/aa45a38ec2cfe97433281b10bbff042c/test-file.zip) html: |-

test-file

- name: attachment_link_for_project api_context: project substitutions: uri_substitution: *uri_substitution markdown: |- [test-file](/uploads/aa45a38ec2cfe97433281b10bbff042c/test-file.zip) html: |-

test-file

- name: attachment_link_for_project_wiki api_context: project_wiki substitutions: uri_substitution: *uri_substitution # TODO: The current frontend example doesn't include the path, need to look into why it does after refactoring to the new golden master approach pending: frontend: 'The current frontend example doesnt include the path, need to look into why it does after refactoring to the new golden master approach' markdown: |- [test-file](test-file.zip) html: |-

test-file

- name: audio markdown: |- ![Sample Audio](https://gitlab.com/gitlab.mp3) html: |-

Sample Audio

- name: audio_and_video_in_lists markdown: |- * ![Sample Audio](https://gitlab.com/1.mp3) * ![Sample Video](https://gitlab.com/2.mp4) 1. ![Sample Video](https://gitlab.com/1.mp4) 2. ![Sample Audio](https://gitlab.com/2.mp3) * [x] ![Sample Audio](https://gitlab.com/1.mp3) * [x] ![Sample Audio](https://gitlab.com/2.mp3) * [x] ![Sample Video](https://gitlab.com/3.mp4) html: |-
  1. Sample Video
  2. Sample Audio
- name: blockquote markdown: |- > This is a blockquote > > This is another one html: |-

This is a blockquote

This is another one

- name: bold markdown: |- **bold** html: |-

bold

- name: bullet_list_style_1 markdown: |- * list item 1 * list item 2 * embedded list item 3 html: |- - name: bullet_list_style_2 markdown: |- - list item 1 - list item 2 * embedded list item 3 html: |- - name: bullet_list_style_3 markdown: |- + list item 1 + list item 2 - embedded list item 3 html: |- - name: code_block_javascript markdown: |- ```javascript console.log('hello world') ``` html: |-
  console.log('hello world')
- name: code_block_plaintext markdown: |- ``` plaintext ``` html: |-
  plaintext
- name: code_block_unknown markdown: |- ```foobar custom_language = >> this << ``` html: |-
  custom_language = >> this <<
- name: color_chips markdown: |- - `#F00` - `#F00A` - `#FF0000` - `#FF0000AA` - `RGB(0,255,0)` - `RGB(0%,100%,0%)` - `RGBA(0,255,0,0.3)` - `HSL(540,70%,50%)` - `HSLA(540,70%,50%,0.3)` html: |- - name: description_list markdown: |-
Frog
Wet green thing
Rabbit
Warm fluffy thing
Punt
Kick a ball
Take a bet
Color
Colour
Any hue except _white_ or **black**
html: |-
Frog
Wet green thing
Rabbit
Warm fluffy thing
Punt
Kick a ball
Take a bet
Color
Colour

Any hue except white or black

- name: details markdown: |-
This is the visible summary of the collapsible section 1. collapsed markdown 2. more collapsed markdown
html: |-
This is the visible summary of the collapsible section
  1. collapsed markdown
  2. more collapsed markdown
- name: diagram_kroki_nomnoml markdown: |- ```nomnoml #stroke: #a86128 [Decorator pattern| [Component||+ operation()] [Client] depends --> [Component] [Decorator|- next: Component] [Decorator] decorates -- [ConcreteComponent] [Component] <:- [Decorator] [Component] <:- [ConcreteComponent] ] ``` html: |- - name: diagram_plantuml markdown: |- ```plantuml Alice -> Bob: Authentication Request Bob --> Alice: Authentication Response Alice -> Bob: Another authentication Request Alice <-- Bob: Another authentication Response ``` html: |- - name: diagram_plantuml_unicode markdown: |- ```plantuml A -> B : Text with norwegian characters: æøå ``` html: |- - name: div markdown: |-
plain text
just a plain ol' div, not much to _expect_!
html: |-
plain text

just a plain ol' div, not much to expect!

- name: emoji markdown: |- :sparkles: :heart: :100: html: |-

💯

- name: emphasis markdown: _emphasized text_ html:

emphasized text

- name: figure markdown: |-
![Elephant at sunset](elephant-sunset.jpg)
An elephant at sunset
![A crocodile wearing crocs](croc-crocs.jpg)
A crocodile wearing _crocs_!
html: |-

Elephant at sunset

An elephant at sunset

A crocodile wearing crocs

A crocodile wearing crocs!

- name: footnotes substitutions: # NOTE: We don't care about verifying specific attribute values here, that should be the # responsibility of unit tests. These tests are about the structure of the HTML. fn_href_substitution: - regex: '(href)(=")(.+?)(")' replacement: '\1\2REF\4' footnote_id_substitution: - regex: '(id)(=")(.+?)(")' replacement: '\1\2ID\4' pending: backend: https://gitlab.com/gitlab-org/gitlab/-/issues/346591 markdown: |- A footnote reference tag looks like this: [^1] This reference tag is a mix of letters and numbers. [^footnote] [^1]: This is the text inside a footnote. [^footnote]: This is another footnote. html: |-

A footnote reference tag looks like this: 1

This reference tag is a mix of letters and numbers. 2

  1. This is the text inside a footnote.

  2. This is another footnote.

- name: frontmatter_json markdown: |- ;;; { "title": "Page title" } ;;; html: |-
{
      "title": "Page title"
    }
- name: frontmatter_toml markdown: |- +++ title = "Page title" +++ html: |-
title = "Page title"
- name: frontmatter_yaml markdown: |- --- title: Page title --- html: |-
title: Page title
- name: hard_break markdown: |- This is a line after a\ hard break html: |-

This is a line after a
hard break

- name: headings markdown: |- # Heading 1 ## Heading 2 ### Heading 3 #### Heading 4 ##### Heading 5 ###### Heading 6 html: |-

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6
- name: horizontal_rule markdown: |- --- html: |-
- name: html_marks markdown: |- * Content editor is ~~great~~amazing. * If the changes LGTM, please MWPS. * The English song Oh I do like to be beside the seaside looks like this in Hebrew: אה, אני אוהב להיות ליד חוף הים. In the computer's memory, this is stored as אה, אני אוהב להיות ליד חוף הים. * The Scream by Edvard Munch. Painted in 1893. * HTML is the standard markup language for creating web pages. * Do not forget to buy milk today. * This is a paragraph and smaller text goes here. * The concert starts at and you'll be able to enjoy the band for at least . * Press Ctrl + C to copy text (Windows). * WWF's goal is to: Build a future where people live in harmony with nature. We hope they succeed. * The error occurred was: Keyboard not found. Press F1 to continue. * The area of a triangle is: 1/2 x b x h, where b is the base, and h is the vertical height. * ㄏㄢˋ * C7H16 + O2 → CO2 + H2O * The **Pythagorean theorem** is often expressed as a2 + b2 = c2 html: |- - name: image markdown: |- ![alt text](https://gitlab.com/logo.png) html: |-

alt text

- name: inline_code markdown: |- `code` html: |-

code

- name: inline_diff markdown: |- * {-deleted-} * {+added+} html: |- - name: label pending: # TODO: There is an error with the frontend HTML to markdown spec adding a double escape (\\) to the label tilde. frontend: 'There is an error with the frontend HTML to markdown spec adding a double escape (\\) to the label tilde.' markdown: |- ~bug html: |-

~bug

- name: link markdown: |- [GitLab](https://gitlab.com) html: |-

GitLab

- name: math markdown: |- This math is inline $`a^2+b^2=c^2`$. This is on a separate line: ```math a^2+b^2=c^2 ``` html: |-

This math is inline a^2+b^2=c^2.

This is on a separate line:

a^2+b^2=c^2
- name: ordered_list markdown: |- 1. list item 1 2. list item 2 3. list item 3 html: |-
  1. list item 1
  2. list item 2
  3. list item 3
- name: ordered_list_with_start_order markdown: |- 134. list item 1 135. list item 2 136. list item 3 html: |-
  1. list item 1
  2. list item 2
  3. list item 3
- name: ordered_task_list markdown: |- 1. [x] hello 2. [x] world 3. [ ] example 1. [ ] of nested 1. [x] task list 2. [ ] items html: |-
  1. hello
  2. world
  3. example
    1. of nested
      1. task list
      2. items
- name: ordered_task_list_with_order markdown: |- 4893. [x] hello 4894. [x] world 4895. [ ] example html: |-
  1. hello
  2. world
  3. example
- name: reference_for_project_wiki api_context: project_wiki substitutions: # NOTE: We don't care about verifying specific attribute values here, that should be the # responsibility of unit tests. These tests are about the structure of the HTML. uri_substitution: *uri_substitution data_attribute_id_substitution: - regex: '(data-user|data-project|data-issue|data-iid|data-merge-request|data-milestone|data-label)(=")(\d+?)(")' replacement: '\1\2ID\4' text_attribute_substitution: - regex: '(title)(=")([^"]*)(")' replacement: '\1\2TEXT\4' path_attribute_id_substitution: - regex: '(group|project)(\d+)' replacement: '\1ID' markdown: |- Hi @gfm_user - thank you for reporting this ~"UX bug" (#1) we hope to fix it in %1.1 as part of !1 html: |-

Hi @gfm_user - thank you for reporting this UX bug (#1) we hope to fix it in %1.1 as part of !1

- name: strike markdown: |- ~~del~~ html: |-

del

- name: table markdown: |- | header | header | |--------|--------| | `code` | cell with **bold** | | ~~strike~~ | cell with _italic_ | # content after table html: |-
header header
code cell with bold
strike cell with italic

content after table

- name: table_of_contents markdown: |- [[_TOC_]] # Lorem Well, that's just like... your opinion.. man. ## Ipsum ### Dolar # Sit amit ### I don't know html: |-

Lorem

Well, that's just like... your opinion.. man.

Ipsum

Dolar

Sit amit

I don't know

- name: task_list markdown: |- * [x] hello * [x] world * [ ] example * [ ] of nested * [x] task list * [ ] items html: |- - name: video markdown: |- ![Sample Video](https://gitlab.com/gitlab.mp4) html: |-

Sample Video

- name: word_break markdown: Fernstraßenbauprivatfinanzierungsgesetz html:

Fernstraßenbauprivatfinanzierungsgesetz