Commit 1380ce73 authored by Brett Walker's avatar Brett Walker Committed by Mayra Cabrera

Add support for testing mermaid, platuml, kroki

in markdown feature spec
parent 8135412c
...@@ -9,7 +9,7 @@ module Banzai ...@@ -9,7 +9,7 @@ module Banzai
# #
class PlantumlFilter < HTML::Pipeline::Filter class PlantumlFilter < HTML::Pipeline::Filter
def call def call
return doc unless doc.at('pre > code[lang="plantuml"]') && settings.plantuml_enabled return doc unless settings.plantuml_enabled? && doc.at('pre > code[lang="plantuml"]')
plantuml_setup plantuml_setup
......
# frozen_string_literal: true # frozen_string_literal: true
if ENV.key?('BENCHMARK') return unless ENV.key?('BENCHMARK')
require 'spec_helper'
require 'erb' require 'spec_helper'
require 'benchmark/ips' require 'erb'
require 'benchmark/ips'
# This benchmarks some of the Banzai pipelines and filters.
# They are not definitive, but can be used by a developer to # This benchmarks some of the Banzai pipelines and filters.
# get a rough idea how the changing or addition of a new filter # They are not definitive, but can be used by a developer to
# will effect performance. # get a rough idea how the changing or addition of a new filter
# # will effect performance.
# Run by: #
# BENCHMARK=1 rspec spec/benchmarks/banzai_benchmark.rb # Run by:
# or # BENCHMARK=1 rspec spec/benchmarks/banzai_benchmark.rb
# rake benchmark:banzai # or
# # rake benchmark:banzai
RSpec.describe 'GitLab Markdown Benchmark', :aggregate_failures do #
include MarkupHelper # rubocop: disable RSpec/TopLevelDescribePath
RSpec.describe 'GitLab Markdown Benchmark', :aggregate_failures do
let_it_be(:feature) { MarkdownFeature.new } include MarkupHelper
let_it_be(:project) { feature.project }
let_it_be(:group) { feature.group } let_it_be(:feature) { MarkdownFeature.new }
let_it_be(:wiki) { feature.wiki } let_it_be(:project) { feature.project }
let_it_be(:wiki_page) { feature.wiki_page } let_it_be(:group) { feature.group }
let_it_be(:markdown_text) { feature.raw_markdown } let_it_be(:wiki) { feature.wiki }
let_it_be(:wiki_page) { feature.wiki_page }
let!(:render_context) { Banzai::RenderContext.new(project, current_user) } let_it_be(:markdown_text) { feature.raw_markdown }
let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
before do let_it_be(:default_context) do
stub_application_setting(asset_proxy_enabled: true) {
stub_application_setting(asset_proxy_secret_key: 'shared-secret') project: project,
stub_application_setting(asset_proxy_url: 'https://assets.example.com') current_user: current_user,
stub_application_setting(asset_proxy_whitelist: %w(gitlab.com *.mydomain.com)) suggestions_filter_enabled: true
}
Banzai::Filter::AssetProxyFilter.initialize_settings end
end
context 'pipelines' do let(:context) do
it 'benchmarks several pipelines' do Banzai::Filter::AssetProxyFilter.transform_context(default_context)
path = 'images/example.jpg' end
gitaly_wiki_file = Gitlab::GitalyClient::WikiFile.new(path: path)
allow(wiki).to receive(:find_file).with(path).and_return(Gitlab::Git::WikiFile.new(gitaly_wiki_file))
allow(wiki).to receive(:wiki_base_path) { '/namespace1/gitlabhq/wikis' }
puts "\n--> Benchmarking Full, Wiki, and Plain pipelines\n" let!(:render_context) { Banzai::RenderContext.new(project, current_user) }
Benchmark.ips do |x| before do
x.config(time: 10, warmup: 2) stub_application_setting(asset_proxy_enabled: true)
stub_application_setting(asset_proxy_secret_key: 'shared-secret')
stub_application_setting(asset_proxy_url: 'https://assets.example.com')
stub_application_setting(asset_proxy_whitelist: %w(gitlab.com *.mydomain.com))
stub_application_setting(plantuml_enabled: true, plantuml_url: 'http://localhost:8080')
stub_application_setting(kroki_enabled: true, kroki_url: 'http://localhost:8000')
x.report('Full pipeline') { markdown(markdown_text, { pipeline: :full }) } Banzai::Filter::AssetProxyFilter.initialize_settings
x.report('Wiki pipeline') { markdown(markdown_text, { pipeline: :wiki, wiki: wiki, page_slug: wiki_page.slug }) } end
x.report('Plain pipeline') { markdown(markdown_text, { pipeline: :plain_markdown }) }
x.compare! context 'pipelines' do
end it 'benchmarks several pipelines' do
end path = 'images/example.jpg'
end gitaly_wiki_file = Gitlab::GitalyClient::WikiFile.new(path: path)
allow(wiki).to receive(:find_file).with(path).and_return(Gitlab::Git::WikiFile.new(gitaly_wiki_file))
allow(wiki).to receive(:wiki_base_path) { '/namespace1/gitlabhq/wikis' }
context 'filters' do puts "\n--> Benchmarking Full, Wiki, and Plain pipelines\n"
let(:context) do
tmp = { project: project, current_user: current_user, render_context: render_context }
Banzai::Filter::AssetProxyFilter.transform_context(tmp)
end
it 'benchmarks all filters in the FullPipeline' do Benchmark.ips do |x|
benchmark_pipeline_filters(:full) x.config(time: 10, warmup: 2)
end
x.report('Full pipeline') { Banzai::Pipeline::FullPipeline.call(markdown_text, context) }
x.report('Wiki pipeline') { Banzai::Pipeline::WikiPipeline.call(markdown_text, context.merge(wiki: wiki, page_slug: wiki_page.slug)) }
x.report('Plain pipeline') { Banzai::Pipeline::PlainMarkdownPipeline.call(markdown_text, context) }
it 'benchmarks all filters in the PlainMarkdownPipeline' do x.compare!
benchmark_pipeline_filters(:plain_markdown)
end end
end end
end
# build up the source text for each filter context 'filters' do
def build_filter_text(pipeline, initial_text) it 'benchmarks all filters in the FullPipeline' do
filter_source = {} benchmark_pipeline_filters(:full)
input_text = initial_text end
pipeline.filters.each do |filter_klass| it 'benchmarks all filters in the PlainMarkdownPipeline' do
filter_source[filter_klass] = input_text benchmark_pipeline_filters(:plain_markdown)
end
end
output = filter_klass.call(input_text, context) # build up the source text for each filter
input_text = output def build_filter_text(pipeline, initial_text)
end filter_source = {}
input_text = initial_text
filter_source pipeline.filters.each do |filter_klass|
filter_source[filter_klass] = input_text
output = filter_klass.call(input_text, context)
input_text = output
end end
def benchmark_pipeline_filters(pipeline_type) filter_source
pipeline = Banzai::Pipeline[pipeline_type] end
filter_source = build_filter_text(pipeline, markdown_text)
puts "\n--> Benchmarking #{pipeline.name.demodulize} filters\n" def benchmark_pipeline_filters(pipeline_type)
pipeline = Banzai::Pipeline[pipeline_type]
filter_source = build_filter_text(pipeline, markdown_text)
Benchmark.ips do |x| puts "\n--> Benchmarking #{pipeline.name.demodulize} filters\n"
x.config(time: 10, warmup: 2)
pipeline.filters.each do |filter_klass| Benchmark.ips do |x|
label = filter_klass.name.demodulize.delete_suffix('Filter').truncate(20) x.config(time: 10, warmup: 2)
x.report(label) { filter_klass.call(filter_source[filter_klass], context) } pipeline.filters.each do |filter_klass|
end label = filter_klass.name.demodulize.delete_suffix('Filter').truncate(20)
x.compare! x.report(label) { filter_klass.call(filter_source[filter_klass], context) }
end end
end
# Fake a `current_user` helper x.compare!
def current_user
feature.user
end end
end end
# Fake a `current_user` helper
def current_user
feature.user
end
end end
...@@ -206,6 +206,9 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do ...@@ -206,6 +206,9 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
# `markdown` helper expects a `@project` and `@group` variable # `markdown` helper expects a `@project` and `@group` variable
@project = @feat.project @project = @feat.project
@group = @feat.group @group = @feat.group
stub_application_setting(plantuml_enabled: true, plantuml_url: 'http://localhost:8080')
stub_application_setting(kroki_enabled: true, kroki_url: 'http://localhost:8000')
end end
let(:project) { @feat.project } # Shadow this so matchers can use it let(:project) { @feat.project } # Shadow this so matchers can use it
...@@ -265,6 +268,18 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do ...@@ -265,6 +268,18 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
aggregate_failures 'ColorFilter' do aggregate_failures 'ColorFilter' do
expect(doc).to parse_colors expect(doc).to parse_colors
end end
aggregate_failures 'MermaidFilter' do
expect(doc).to parse_mermaid
end
aggregate_failures 'PlantumlFilter' do
expect(doc).to parse_plantuml
end
aggregate_failures 'KrokiFilter' do
expect(doc).to parse_kroki
end
end end
end end
...@@ -338,6 +353,18 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do ...@@ -338,6 +353,18 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
aggregate_failures 'ColorFilter' do aggregate_failures 'ColorFilter' do
expect(doc).to parse_colors expect(doc).to parse_colors
end end
aggregate_failures 'MermaidFilter' do
expect(doc).to parse_mermaid
end
aggregate_failures 'PlantumlFilter' do
expect(doc).to parse_plantuml
end
aggregate_failures 'KrokiFilter' do
expect(doc).to parse_kroki
end
end end
end end
......
...@@ -358,3 +358,17 @@ For details see the [Mermaid official page][mermaid]. ...@@ -358,3 +358,17 @@ For details see the [Mermaid official page][mermaid].
[mermaid]: https://mermaidjs.github.io/ "Mermaid website" [mermaid]: https://mermaidjs.github.io/ "Mermaid website"
### PLantUML
```plantuml
Bob -> Sara : Hello
```
### Kroki
```nomnoml
[Pirate|eyeCount: Int|raid();pillage()|
[beard]--[parrot]
[beard]-:>[foul mouth]
]
```
...@@ -246,6 +246,33 @@ module MarkdownMatchers ...@@ -246,6 +246,33 @@ module MarkdownMatchers
end end
end end
end end
# MermaidFilter
matcher :parse_mermaid do
set_default_markdown_messages
match do |actual|
expect(actual).to have_selector('code.js-render-mermaid')
end
end
# PLantumlFilter
matcher :parse_plantuml do
set_default_markdown_messages
match do |actual|
expect(actual).to have_link(href: 'http://localhost:8080/png/U9npoazIqBLJ24uiIbImKl18pSd9vm80EtS5lW00')
end
end
# KrokiFilter
matcher :parse_kroki do
set_default_markdown_messages
match do |actual|
expect(actual).to have_link(href: 'http://localhost:8000/nomnoml/svg/eNqLDsgsSixJrUmtTHXOL80rsVLwzCupKUrMTNHQtC7IzMlJTE_V0KzhUlCITkpNLEqJ1dWNLkgsKsoviUUSs7KLTssvzVHIzS8tyYjligUAMhEd0g==')
end
end
end end
# Monkeypatch the matcher DSL so that we can reduce some noisy duplication for # Monkeypatch the matcher DSL so that we can reduce some noisy duplication for
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment