Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'doc/development/gitlab_flavored_markdown/specification_guide/index.md')
-rw-r--r--doc/development/gitlab_flavored_markdown/specification_guide/index.md143
1 files changed, 112 insertions, 31 deletions
diff --git a/doc/development/gitlab_flavored_markdown/specification_guide/index.md b/doc/development/gitlab_flavored_markdown/specification_guide/index.md
index 756b87cd407..c1227e5d33f 100644
--- a/doc/development/gitlab_flavored_markdown/specification_guide/index.md
+++ b/doc/development/gitlab_flavored_markdown/specification_guide/index.md
@@ -345,8 +345,50 @@ For the [Markdown snapshot testing](#markdown-snapshot-testing) to work
properly, you must account for these differences in a way that ensures the tests are reliable,
and always behave the same across different test runs or environments.
-To account for these differences, there is a process called **_normalization_**. Normalization
-allows custom regular expressions with
+To account for these differences, there is a process called **_normalization_**. Several ways to approach normalization exist:
+
+1. Fixture-based normalization
+1. Environment-variable-based normalization
+1. Regex-based normalization
+
+#### Fixture-based normalization
+
+Fixture-based normalization should be used whenever possible, because it is simpler and easier to
+understand than regex-based normalization.
+
+The [Markdown snapshot testing](#markdown-snapshot-testing) uses RSpec to generate the
+[example snapshot files](#example-snapshot-files). RSpec enables you to:
+
+- Use the same powerful fixture support and helpers as all the rest of the GitLab RSpec suite.
+- Use fixtures to control the state of the database when the example snapshots are generated.
+- Extract this fixture setup to an RSpec shared context. This shared context is used to ensure
+ the same database state exists wherever the snapshot tests are run, either by the CI suite, or
+ locally via [`run-snapshot-tests.sh`](#run-snapshot-testssh-script).
+
+You can see the RSpec shared context containing these fixtures in
+[`spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb).
+
+#### Environment-variable-based normalization
+
+In some cases, fixtures may not be usable, because they do not provide control over the varying
+values. In these cases, we can introduce support for a environment variable into the production
+code, which allows us to override the randommness in our test environment when we are
+generating the HTML for footnote examples. Even though it is in the production code path, it has
+no effect unless it is explicitly set, therefore it is innocuous. It allows us to avoid
+the more-complex regex-based normalization described below.
+
+The current example of this is when normally random footnote IDs are overridden to be deterministic
+by setting `GITLAB_TEST_FOOTNOTE_ID`. It is set along with the fixtures setup in the
+[`spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb`](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb)
+shared context.
+
+#### Regex-based normalization
+
+If neither fixture-based nor environment-variable-based normalization can be used, use regex-based
+normalization. It is powerful, but more complex, and requires more maintenance.
+It requires referring to specific examples by name, and crafting the proper regexes.
+
+Regex-based normalization allows custom regular expressions with
[_capturing groups_](https://ruby-doc.org/core-3.1.2/Regexp.html#class-Regexp-label-Capturing)
to be applied to two different versions of HTML or JSON for a given Markdown example,
and the contents of the captured groups can be replaced with the same fixed values.
@@ -653,10 +695,16 @@ is the manually updated canonical Markdown+HTML examples for GLFM extensions.
- It contains examples in the [standard backtick-delimited `spec.txt` format](#various-markdown-specifications),
each of which contain a Markdown example and the corresponding canonical HTML.
+- For all GitLab examples, the "extension" annotation after the backticks should consist of only
+ `example gitlab`. It does not currently include any additional extension annotations describing
+ the specific Markdown, unlike the GitHub Flavored Markdown examples, which do include
+ these additional annotations (such as `example strikethrough`).
- The `update-specification.rb` script inserts it as new sections before the appendix
of generated `spec.txt`.
-- It should consist of `H1` header sections, with all examples nested exactly 2 levels deep within `H2`
- header sections.
+- It should consist of `H1` header sections, with all examples nested either 2 or 3 levels deep
+ within `H2` or `H3` header sections.
+- `H3` header sections must be nested within `H2` header sections. They cannot be
+ nested directly within `H1` header sections.
`glfm_specification/input/gitlab_flavored_markdown/glfm_canonical_examples.txt` sample entries:
@@ -670,7 +718,7 @@ The actual file should not have these prefixed `|` characters.
|
|## Strong but with two asterisks
|
-|```````````````````````````````` example
+|```````````````````````````````` example gitlab
|**bold**
|.
|<p><strong>bold</strong></p>
@@ -680,7 +728,7 @@ The actual file should not have these prefixed `|` characters.
|
|## Strong but with HTML
|
-|```````````````````````````````` example
+|```````````````````````````````` example gitlab
|<strong>
|bold
|</strong>
@@ -738,7 +786,7 @@ The following optional entries are supported for each example. They all default
`glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml` sample entry:
```yaml
-07_99_an_example_with_incomplete_wysiwyg_implementation_1:
+07_99_00_an_example_with_incomplete_wysiwyg_implementation_1:
skip_update_example_snapshots: 'An explanation of the reason for skipping.'
skip_update_example_snapshot_html_static: 'An explanation of the reason for skipping.'
skip_update_example_snapshot_html_wysiwyg: 'An explanation of the reason for skipping.'
@@ -771,40 +819,73 @@ to be specified for a Markdown example.
00_uri: &00_uri
- regex: '(href|data-src)(=")(.*?)(test-file\.(png|zip)")'
replacement: '\1\2URI_PREFIX\4'
-01_01__section_one__example_containing_a_uri__001:
+01_01_00__section_one__example_containing_a_uri__001:
html:
static:
canonical:
- 01_01_uri: *00_uri
+ 01_01_00_uri: *00_uri
snapshot:
- 01_01_uri: *00_uri
+ 01_01_00_uri: *00_uri
wysiwyg:
- 01_01_uri: *00_uri
+ 01_01_00_uri: *00_uri
prosemirror_json:
- 01_01_uri: *00_uri
-07_01__gitlab_specific_markdown__footnotes__001:
+ 01_01_00_uri: *00_uri
+07_01_00__gitlab_specific_markdown__footnotes__001:
# YAML anchors which are only shared within a single example should be defined within the example
shared:
- 07_01_href: &07_01_href
+ 07_01_00_href: &07_01_00_href
- regex: '(href)(=")(.+?)(")'
replacement: '\1\2REF\4'
- 07_01_id: &07_01_id
+ 07_01_00_id: &07_01_00_id
- regex: '(id)(=")(.+?)(")'
replacement: '\1\2ID\4'
html:
static:
canonical:
- 07_01_href: *07_01_href
- 07_01_id: *07_01_id
+ 07_01_00_href: *07_01_00_href
+ 07_01_00_id: *07_01_00_id
snapshot:
- 07_01_href: *07_01_href
- 07_01_id: *07_01_id
+ 07_01_00_href: *07_01_00_href
+ 07_01_00_id: *07_01_00_id
wysiwyg:
- 07_01_href: *07_01_href
- 07_01_id: *07_01_id
+ 07_01_00_href: *07_01_00_href
+ 07_01_00_id: *07_01_00_id
prosemirror_json:
- 07_01_href: *07_01_href
- 07_01_id: *07_01_id
+ 07_01_00_href: *07_01_00_href
+ 07_01_00_id: *07_01_00_id
+```
+
+##### `glfm_example_metadata.yml`
+
+[`glfm_specification/input/gitlab_flavored_markdown/glfm_example_metadata.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/gitlab_flavored_markdown/glfm_example_metadata.yml)
+allows control over other aspects of the snapshot example generation process.
+
+- It is manually updated.
+- The `ee` fields determine whether the example is an EE-only example. If the `ee` field is `true`,
+ the example will only be run by `ee/spec/requests/api/markdown_snapshot_spec.rb`, not by
+ `spec/requests/api/markdown_snapshot_spec.rb`.
+- The `api_request_override_path` field overrides the API endpoint path which is used to
+ generate the `static` HTML for the specifed example. Different endpoints can generate different
+ HTML in some cases, so we want to be able to exercise different API endpoints for the same
+ Markdown. By default, the `/markdown` endpoint is used.
+
+`glfm_specification/input/gitlab_flavored_markdown/glfm_example_metadata.yml` sample entries:
+
+```yaml
+---
+08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__001:
+ api_request_override_path: /groups/glfm_group/preview_markdown
+08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__002:
+ api_request_override_path: /glfm_group/glfm_project/preview_markdown
+08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__003:
+ api_request_override_path: /glfm_group/glfm_project/preview_markdown
+08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__004:
+ api_request_override_path: /-/snippets/preview_markdown
+08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__005:
+ api_request_override_path: /glfm_group/glfm_project/-/wikis/new_page/preview_markdown
+08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__006:
+ ee: true
+ api_request_override_path: /groups/glfm_group/-/wikis/new_page/preview_markdown
```
#### Output specification files
@@ -891,19 +972,19 @@ CommonMark, GFM, and GLFM example names, each with a unique canonical name.
`glfm_specification/example_snapshots/examples_index.yml` sample entries:
```yaml
-02_01_preliminaries_characters_and_lines_1:
+02_01_00_preliminaries_characters_and_lines_1:
spec_txt_example_position: 1
source_specification: commonmark
-03_01_blocks_and_inlines_precedence_1:
+03_01_00_blocks_and_inlines_precedence_1:
spec_txt_example_position: 12
source_specification: commonmark
-05_03_container_blocks_task_list_items_1:
+05_03_00_container_blocks_task_list_items_1:
spec_txt_example_position: 279
source_specification: github
-06_04_inlines_emphasis_and_strong_emphasis_1:
+06_04_00_inlines_emphasis_and_strong_emphasis_1:
spec_txt_example_position: 360
source_specification: github
-07_01_audio_link_1:
+07_01_00_audio_link_1:
spec_txt_example_position: 301
source_specification: gitlab
```
@@ -923,7 +1004,7 @@ for each entry in `glfm_specification/example_snapshots/examples_index.yml`
`glfm_specification/example_snapshots/markdown.yml` sample entry:
```yaml
-06_04_inlines_emphasis_and_strong_emphasis_1: |
+06_04_00_inlines_emphasis_and_strong_emphasis_1: |
*foo bar*
```
@@ -958,7 +1039,7 @@ Any exceptions or failures which occur when generating HTML are replaced with an
`glfm_specification/example_snapshots/html.yml` sample entry:
```yaml
-06_04_inlines_emphasis_and_strong_emphasis_1:
+06_04_00_inlines_emphasis_and_strong_emphasis_1:
canonical: |
<p><em>foo bar</em></p>
static: |
@@ -983,7 +1064,7 @@ contains the ProseMirror JSON for each entry in `glfm_specification/example_snap
`glfm_specification/example_snapshots/prosemirror_json.yml` sample entry:
```yaml
-06_04_inlines_emphasis_and_strong_emphasis_1: |-
+06_04_00_inlines_emphasis_and_strong_emphasis_1: |-
{
"type": "doc",
"content": [