diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-17 03:08:52 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-17 03:08:52 +0300 |
commit | 159a7788ca18140da04e24c45ab557da99864789 (patch) | |
tree | 929bc82d0fbdd8fdcd6b522bc1e1f9bcb71db3a8 /spec/scripts | |
parent | cffe2c2c348d86d67298fa6516d49c36d696ab2d (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/scripts')
-rw-r--r-- | spec/scripts/lib/glfm/shared_spec.rb | 25 | ||||
-rw-r--r-- | spec/scripts/lib/glfm/update_example_snapshots_spec.rb | 316 | ||||
-rw-r--r-- | spec/scripts/lib/glfm/update_specification_spec.rb | 4 |
3 files changed, 339 insertions, 6 deletions
diff --git a/spec/scripts/lib/glfm/shared_spec.rb b/spec/scripts/lib/glfm/shared_spec.rb index 7626b4bd946..f6792b93718 100644 --- a/spec/scripts/lib/glfm/shared_spec.rb +++ b/spec/scripts/lib/glfm/shared_spec.rb @@ -3,15 +3,32 @@ require 'fast_spec_helper' require_relative '../../../../scripts/lib/glfm/shared' RSpec.describe Glfm::Shared do + let(:instance) do + Class.new do + include Glfm::Shared + end.new + end + + describe '#run_external_cmd' do + it 'works' do + expect(instance.run_external_cmd('echo "hello"')).to eq("hello\n") + end + + context 'when command fails' do + it 'raises error' do + invalid_cmd = 'ls nonexistent_file' + expect(instance).to receive(:warn).with(/Error running command `#{invalid_cmd}`/) + expect(instance).to receive(:warn).with(/nonexistent_file.*no such file/i) + expect { instance.run_external_cmd(invalid_cmd) }.to raise_error(RuntimeError) + end + end + end + describe '#output' do # NOTE: The #output method is normally always mocked, to prevent output while the specs are # running. However, in order to provide code coverage for the method, we have to invoke # it at least once. it 'has code coverage' do - clazz = Class.new do - include Glfm::Shared - end - instance = clazz.new allow(instance).to receive(:puts) instance.output('') end diff --git a/spec/scripts/lib/glfm/update_example_snapshots_spec.rb b/spec/scripts/lib/glfm/update_example_snapshots_spec.rb new file mode 100644 index 00000000000..169f5d1c5a6 --- /dev/null +++ b/spec/scripts/lib/glfm/update_example_snapshots_spec.rb @@ -0,0 +1,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 diff --git a/spec/scripts/lib/glfm/update_specification_spec.rb b/spec/scripts/lib/glfm/update_specification_spec.rb index 91399d16b96..941883cd1e0 100644 --- a/spec/scripts/lib/glfm/update_specification_spec.rb +++ b/spec/scripts/lib/glfm/update_specification_spec.rb @@ -23,7 +23,7 @@ RSpec.describe Glfm::UpdateSpecification, '#process' do title: GitHub Flavored Markdown Spec version: 0.29 date: '2019-04-06' - license: '[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)' + license: '[CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)' ... # Introduction @@ -141,7 +141,7 @@ RSpec.describe Glfm::UpdateSpecification, '#process' do expect(glfm_contents).not_to match(/^version: \d\.\d/m) expect(glfm_contents).not_to match(/^date: /m) expect(glfm_contents).not_to match(/^license: /m) - expect(glfm_contents).to match(/#{Regexp.escape(described_class::GLFM_SPEC_TXT_HEADER)}\n/m) + expect(glfm_contents).to match(/#{Regexp.escape(described_class::GLFM_SPEC_TXT_HEADER)}\n/mo) end it 'replaces the intro section with the GitLab version' do |