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

update_example_snapshots_spec.rb « glfm « lib « scripts « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 169f5d1c5a6da252149ebd89df657bf07dd5c3aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# frozen_string_literal: true
require 'fast_spec_helper'
require_relative '../../../../scripts/lib/glfm/update_example_snapshots'

RSpec.describe Glfm::UpdateExampleSnapshots, '#process' do
  subject { described_class.new }

  # GLFM input files
  let(:glfm_spec_txt_path) { described_class::GLFM_SPEC_TXT_PATH }
  let(:glfm_spec_txt_local_io) { StringIO.new(glfm_spec_txt_contents) }
  let(:glfm_example_status_yml_path) { described_class::GLFM_EXAMPLE_STATUS_YML_PATH }
  let(:glfm_example_status_yml_io) { StringIO.new(glfm_example_status_yml_contents) }

  # Example Snapshot (ES) output files
  let(:es_examples_index_yml_path) { described_class::ES_EXAMPLES_INDEX_YML_PATH }
  let(:es_examples_index_yml_io) { StringIO.new }
  let(:es_markdown_yml_path) { described_class::ES_MARKDOWN_YML_PATH }
  let(:es_markdown_yml_io) { StringIO.new }
  let(:es_html_yml_path) { described_class::ES_HTML_YML_PATH }
  let(:es_html_yml_io) { StringIO.new }
  let(:es_prosemirror_json_yml_path) { described_class::ES_PROSEMIRROR_JSON_YML_PATH }
  let(:es_prosemirror_json_yml_io) { StringIO.new }

  # Internal tempfiles
  let(:static_html_tempfile_path) { Tempfile.new.path }

  let(:glfm_spec_txt_contents) do
    <<~GLFM_SPEC_TXT_CONTENTS
      ---
      title: GitLab Flavored Markdown Spec
      ...

      # Introduction

      GLFM intro text...

      # Inlines

      ## Strong

      ```````````````````````````````` example
      __bold__
      .
      <p><strong>bold</strong></p>
      ````````````````````````````````

      ```````````````````````````````` example strikethrough
      __bold with more text__
      .
      <p><strong>bold with more text</strong></p>
      ````````````````````````````````

      <div class="extension">

      ## Strikethrough (extension)

      GFM enables the `strikethrough` extension.

      ```````````````````````````````` example strikethrough
      ~~Hi~~ Hello, world!
      .
      <p><del>Hi</del> Hello, world!</p>
      ````````````````````````````````

      </div>

      End of last GitHub examples section.

      # First GitLab-Specific Section with Examples

      ## Strong but with two asterisks

      ```````````````````````````````` example gitlab strong
      **bold**
      .
      <p><strong>bold</strong></p>
      ````````````````````````````````

      # Second GitLab-Specific Section with Examples

      ## Strong but with HTML

      ```````````````````````````````` example gitlab strong
      <strong>
      bold
      </strong>
      .
      <p><strong>
      bold
      </strong></p>
      ````````````````````````````````

      <!-- END TESTS -->

      # Appendix

      Appendix text.
    GLFM_SPEC_TXT_CONTENTS
  end

  let(:glfm_example_status_yml_contents) do
    <<~GLFM_EXAMPLE_STATUS_YML_CONTENTS
      ---
      - 07_01_first_gitlab_specific_section_with_examples_strong_but_with_two_asterisks:
        skip_update_example_snapshots: false
        skip_running_snapshot_static_html_tests: false
        skip_running_snapshot_wysiwyg_html_tests: false
        skip_running_snapshot_prosemirror_json_tests: false
        skip_running_conformance_static_tests: false
        skip_running_conformance_wysiwyg_tests: false
      - 07_02_first_gitlab_specific_section_with_examples_strong_but_with_html:
        skip_update_example_snapshots: false
        skip_running_snapshot_static_html_tests: false
        skip_running_snapshot_wysiwyg_html_tests: false
        skip_running_snapshot_prosemirror_json_tests: false
        skip_running_conformance_static_tests: false
        skip_running_conformance_wysiwyg_tests: false
    GLFM_EXAMPLE_STATUS_YML_CONTENTS
  end

  before do
    # We mock out the URI and local file IO objects with real StringIO, instead of just mock
    # objects. This gives better and more realistic coverage, while still avoiding
    # actual network and filesystem I/O during the spec run.

    # input files
    allow(File).to receive(:open).with(glfm_spec_txt_path) { glfm_spec_txt_local_io }
    allow(File).to receive(:open).with(glfm_example_status_yml_path) { glfm_example_status_yml_io }

    # output files
    allow(File).to receive(:open).with(es_examples_index_yml_path, 'w') { es_examples_index_yml_io }
    allow(File).to receive(:open).with(es_html_yml_path, 'w') { es_html_yml_io }
    allow(File).to receive(:open).with(es_prosemirror_json_yml_path, 'w') { es_prosemirror_json_yml_io }

    # output files which are also input files
    allow(File).to receive(:open).with(es_markdown_yml_path, 'w') { es_markdown_yml_io }
    allow(File).to receive(:open).with(es_markdown_yml_path) { es_markdown_yml_io }

    # Allow normal opening of Tempfile files created during script execution.
    tempfile_basenames = [
      described_class::MARKDOWN_TEMPFILE_BASENAME[0],
      described_class::STATIC_HTML_TEMPFILE_BASENAME[0],
      described_class::WYSIWYG_HTML_AND_JSON_TEMPFILE_BASENAME[0]
    ].join('|')
    # NOTE: This approach with a single regex seems to be the only way this can work. If you
    # attempt to have multiple `allow...and_call_original` with `any_args`, the mocked
    # parameter matching will fail to match the second one.
    tempfiles_regex = /(#{tempfile_basenames})/
    allow(File).to receive(:open).with(tempfiles_regex, any_args).and_call_original

    # Prevent console output when running tests
    allow(subject).to receive(:output)
  end

  describe 'writing examples_index.yml' do
    let(:es_examples_index_yml_contents) { reread_io(es_examples_index_yml_io) }

    it 'writes the correct content' do
      subject.process(skip_static_and_wysiwyg: true)

      expected =
        <<~ES_EXAMPLES_INDEX_YML_CONTENTS
          ---
          02_01__inlines__strong__01:
            spec_txt_example_position: 1
            source_specification: commonmark
          02_01__inlines__strong__02:
            spec_txt_example_position: 2
            source_specification: github
          02_02__inlines__strikethrough_extension__01:
            spec_txt_example_position: 3
            source_specification: github
          03_01__first_gitlab_specific_section_with_examples__strong_but_with_two_asterisks__01:
            spec_txt_example_position: 4
            source_specification: gitlab
          04_01__second_gitlab_specific_section_with_examples__strong_but_with_html__01:
            spec_txt_example_position: 5
            source_specification: gitlab
        ES_EXAMPLES_INDEX_YML_CONTENTS
      expect(es_examples_index_yml_contents).to eq(expected)
    end
  end

  describe 'writing markdown.yml' do
    let(:es_markdown_yml_contents) { reread_io(es_markdown_yml_io) }

    it 'writes the correct content' do
      subject.process(skip_static_and_wysiwyg: true)

      expected =
        <<~ES_MARKDOWN_YML_CONTENTS
          ---
          02_01__inlines__strong__01: |
            __bold__
          02_01__inlines__strong__02: |
            __bold with more text__
          02_02__inlines__strikethrough_extension__01: |
            ~~Hi~~ Hello, world!
          03_01__first_gitlab_specific_section_with_examples__strong_but_with_two_asterisks__01: |
            **bold**
          04_01__second_gitlab_specific_section_with_examples__strong_but_with_html__01: |
            <strong>
            bold
            </strong>
        ES_MARKDOWN_YML_CONTENTS

      expect(es_markdown_yml_contents).to eq(expected)
    end
  end

  describe 'writing html.yml and prosemirror_json.yml' do
    let(:es_html_yml_contents) { reread_io(es_html_yml_io) }
    let(:es_prosemirror_json_yml_contents) { reread_io(es_prosemirror_json_yml_io) }

    let(:glfm_example_status_yml_contents) do
      <<~GLFM_EXAMPLE_STATUS_YML_CONTENTS
        ---
        - 02_01_gitlab_specific_section_with_examples_strong_but_with_two_asterisks:
          skip_update_example_snapshots: false
          skip_running_snapshot_static_html_tests: false
          skip_running_snapshot_wysiwyg_html_tests: false
          skip_running_snapshot_prosemirror_json_tests: false
          skip_running_conformance_static_tests: false
          skip_running_conformance_wysiwyg_tests: false
      GLFM_EXAMPLE_STATUS_YML_CONTENTS
    end

    let(:glfm_spec_txt_contents) do
      <<~GLFM_SPEC_TXT_CONTENTS
        ---
        title: GitLab Flavored Markdown Spec
        ...

        # Introduction

        # GitLab-Specific Section with Examples

        ## Strong but with two asterisks

        ```````````````````````````````` example gitlab strong
        **bold**
        .
        <p><strong>bold</strong></p>
        ````````````````````````````````
        <!-- END TESTS -->

        # Appendix

        Appendix text.
      GLFM_SPEC_TXT_CONTENTS
    end

    before do
      # NOTE: This is a necessary to avoid an `error Couldn't find an integrity file` error
      #   when invoking `yarn jest ...` on CI from within an RSpec job. It could be solved by
      #   adding `.yarn-install` to be included in the RSpec CI job, but that would be a performance
      #   hit to all RSpec jobs. We could also make a dedicate job just for this spec. However,
      #   since this is just a single script, those options may not be justified.
      described_class.new.run_external_cmd('yarn install') if ENV['CI']
    end

    # NOTE: Both `html.yml` and `prosemirror_json.yml` generation are tested in a single example, to
    # avoid slower tests, because generating the static HTML is slow due to the need to invoke
    # the rails environment. We could have separate sections, but this would require an extra flag
    # to the `process` method to independently skip static vs. WYSIWYG, which is not worth the effort.
    it 'writes the correct content' do
      subject.process

      expected_html =
        <<~ES_HTML_YML_CONTENTS
          ---
          02_01__gitlab_specific_section_with_examples__strong_but_with_two_asterisks__01:
            canonical: |
              <p><strong>bold</strong></p>
            static: |-
              <p data-sourcepos="1:1-1:8" dir="auto"><strong>bold</strong></p>
            wysiwyg: |-
              <p><strong>bold</strong></p>
        ES_HTML_YML_CONTENTS

      expected_prosemirror_json =
        <<~ES_PROSEMIRROR_JSON_YML_CONTENTS
          ---
          02_01__gitlab_specific_section_with_examples__strong_but_with_two_asterisks__01: |-
            {
              "type": "doc",
              "content": [
                {
                  "type": "paragraph",
                  "content": [
                    {
                      "type": "text",
                      "marks": [
                        {
                          "type": "bold"
                        }
                      ],
                      "text": "bold"
                    }
                  ]
                }
              ]
            }
        ES_PROSEMIRROR_JSON_YML_CONTENTS

      expect(es_html_yml_contents).to eq(expected_html)
      expect(es_prosemirror_json_yml_contents).to eq(expected_prosemirror_json)
    end
  end

  def reread_io(io)
    # Reset the io StringIO to the beginning position of the buffer
    io.seek(0)
    io.read
  end
end