"Fossies" - the Fresh Open Source Software Archive

Member "asciidoctor-2.0.10/test/converter_test.rb" (1 Jun 2019, 27569 Bytes) of package /linux/www/asciidoctor-2.0.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Ruby source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "converter_test.rb": 2.0.7_vs_2.0.8.

    1 # frozen_string_literal: true
    2 require_relative 'test_helper'
    3 require 'tilt' unless defined? ::Tilt.new
    4 
    5 context 'Converter' do
    6   context 'View options' do
    7     test 'should set Haml format to html5 for html5 backend' do
    8       doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
    9       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   10       selected = doc.converter.find_converter('paragraph')
   11       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   12       assert_kind_of Tilt::HamlTemplate, selected.templates['paragraph']
   13       assert_equal :html5, selected.templates['paragraph'].options[:format]
   14     end
   15 
   16     test 'should set Haml format to xhtml for docbook backend' do
   17       doc = Asciidoctor::Document.new [], backend: 'docbook5', template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
   18       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   19       selected = doc.converter.find_converter('paragraph')
   20       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   21       assert_kind_of Tilt::HamlTemplate, selected.templates['paragraph']
   22       assert_equal :xhtml, selected.templates['paragraph'].options[:format]
   23     end
   24 
   25     test 'should configure Slim to resolve includes in specified template dirs' do
   26       template_dirs = [(fixture_path 'custom-backends/slim'), (fixture_path 'custom-backends/slim-overrides')]
   27       doc = Asciidoctor::Document.new [], template_dirs: template_dirs, template_cache: false
   28       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   29       selected = doc.converter.find_converter('paragraph')
   30       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   31       assert_kind_of Slim::Template, selected.templates['paragraph']
   32       assert_equal template_dirs.reverse.map {|dir| File.expand_path dir }, selected.templates['paragraph'].options[:include_dirs]
   33     end
   34 
   35     test 'should coerce template_dirs option to an Array' do
   36       template_dirs = fixture_path 'custom-backends/slim'
   37       doc = Asciidoctor::Document.new [], template_dirs: template_dirs, template_cache: false
   38       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   39       selected = doc.converter.find_converter('paragraph')
   40       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   41       assert_kind_of Array, (selected.instance_variable_get :@template_dirs)
   42     end
   43 
   44     test 'should set Slim format to html for html5 backend' do
   45       doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/slim'), template_cache: false
   46       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   47       selected = doc.converter.find_converter('paragraph')
   48       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   49       assert_kind_of Slim::Template, selected.templates['paragraph']
   50       assert_equal :html, selected.templates['paragraph'].options[:format]
   51     end
   52 
   53     test 'should set Slim format to nil for docbook backend' do
   54       doc = Asciidoctor::Document.new [], backend: 'docbook5', template_dir: (fixture_path 'custom-backends/slim'), template_cache: false
   55       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   56       selected = doc.converter.find_converter('paragraph')
   57       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   58       assert_kind_of Slim::Template, selected.templates['paragraph']
   59       assert_nil selected.templates['paragraph'].options[:format]
   60     end
   61 
   62     test 'should set safe mode of Slim AsciiDoc engine to match document safe mode when Slim >= 3' do
   63       doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/slim'), template_cache: false, safe: :unsafe
   64       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   65       selected = doc.converter.find_converter('paragraph')
   66       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   67       slim_asciidoc_opts = selected.instance_variable_get(:@engine_options)[:slim][:asciidoc]
   68       assert_equal({ safe: Asciidoctor::SafeMode::UNSAFE }, slim_asciidoc_opts)
   69     end
   70 
   71     test 'should support custom template engine options for known engine' do
   72       doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/slim'), template_cache: false, template_engine_options: { slim: { pretty: true } }
   73       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   74       selected = doc.converter.find_converter('paragraph')
   75       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   76       assert_kind_of Slim::Template, selected.templates['paragraph']
   77       assert_equal true, selected.templates['paragraph'].options[:pretty]
   78     end
   79 
   80     test 'should support custom template engine options' do
   81       doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/slim'), template_cache: false, template_engine_options: { slim: { pretty: true } }
   82       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   83       selected = doc.converter.find_converter('paragraph')
   84       assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   85       assert_kind_of Slim::Template, selected.templates['paragraph']
   86       assert_equal false, selected.templates['paragraph'].options[:sort_attrs]
   87       assert_equal true, selected.templates['paragraph'].options[:pretty]
   88     end
   89   end
   90 
   91   context 'Custom backends' do
   92     test 'should load Haml templates for default backend' do
   93       doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
   94       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
   95       %w(paragraph sidebar).each do |node_name|
   96         selected = doc.converter.find_converter node_name
   97         assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
   98         assert_kind_of Tilt::HamlTemplate, selected.templates[node_name]
   99         assert_equal %(block_#{node_name}.html.haml), File.basename(selected.templates[node_name].file)
  100       end
  101     end
  102 
  103     test 'should set outfilesuffix according to backend info' do
  104       doc = Asciidoctor.load 'content'
  105       doc.convert
  106       assert_equal '.html', doc.attributes['outfilesuffix']
  107 
  108       doc = Asciidoctor.load 'content', template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
  109       doc.convert
  110       assert_equal '.html', doc.attributes['outfilesuffix']
  111     end
  112 
  113     test 'should not override outfilesuffix attribute if locked' do
  114       doc = Asciidoctor.load 'content', attributes: { 'outfilesuffix' => '.foo' }
  115       doc.convert
  116       assert_equal '.foo', doc.attributes['outfilesuffix']
  117 
  118       doc = Asciidoctor.load 'content', template_dir: (fixture_path 'custom-backends/haml'), template_cache: false, attributes: { 'outfilesuffix' => '.foo' }
  119       doc.convert
  120       assert_equal '.foo', doc.attributes['outfilesuffix']
  121     end
  122 
  123     test 'should load Haml templates for docbook5 backend' do
  124       doc = Asciidoctor::Document.new [], backend: 'docbook5', template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
  125       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
  126       %w(paragraph).each do |node_name|
  127         selected = doc.converter.find_converter node_name
  128         assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
  129         assert_kind_of Tilt::HamlTemplate, selected.templates[node_name]
  130         assert_equal %(block_#{node_name}.xml.haml), File.basename(selected.templates[node_name].file)
  131       end
  132     end
  133 
  134     test 'should use Haml templates in place of built-in templates' do
  135       input = <<~'EOS'
  136       = Document Title
  137       Author Name
  138 
  139       == Section One
  140 
  141       Sample paragraph
  142 
  143       .Related
  144       ****
  145       Sidebar content
  146       ****
  147       EOS
  148 
  149       output = convert_string_to_embedded input, template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
  150       assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p', output, 1
  151       assert_xpath '//aside', output, 1
  152       assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p/following-sibling::aside', output, 1
  153       assert_xpath '//aside/header/h1[text()="Related"]', output, 1
  154       assert_xpath '//aside/header/following-sibling::p[text()="Sidebar content"]', output, 1
  155     end
  156 
  157     test 'should allow custom backend to emulate a known backend' do
  158       doc = Asciidoctor.load 'content', backend: 'html5-tweaks:html', template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
  159       assert doc.basebackend? 'html'
  160       assert_equal 'html5-tweaks', doc.backend
  161       converter = doc.converter
  162       assert_kind_of Asciidoctor::Converter::TemplateConverter, (converter.find_converter 'embedded')
  163       refute_kind_of Asciidoctor::Converter::TemplateConverter, (converter.find_converter 'admonition')
  164       assert_equal '<p>content</p>', doc.convert
  165     end
  166 
  167     test 'should create template converter even when a converter is not registered for the specified backend' do
  168       input = 'paragraph content'
  169       output = convert_string_to_embedded input, backend: :unknown, template_dir: (fixture_path 'custom-backends/haml/html5-tweaks'), template_cache: false
  170       assert_equal '<p>paragraph content</p>', output
  171     end
  172 
  173     test 'should use built-in global cache to cache templates' do
  174       begin
  175         Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
  176         template_dir = fixture_path 'custom-backends/haml'
  177         doc = Asciidoctor::Document.new [], template_dir: template_dir
  178         doc.converter
  179         caches = Asciidoctor::Converter::TemplateConverter.caches
  180         if defined? ::Concurrent::Map
  181           assert_kind_of ::Concurrent::Map, caches[:templates]
  182           refute_empty caches[:templates]
  183           paragraph_template_before = caches[:templates].values.find {|t| File.basename(t.file) == 'block_paragraph.html.haml' }
  184           refute_nil paragraph_template_before
  185 
  186           # should use cache
  187           doc = Asciidoctor::Document.new [], template_dir: template_dir
  188           template_converter = doc.converter.find_converter('paragraph')
  189           paragraph_template_after = template_converter.templates['paragraph']
  190           refute_nil paragraph_template_after
  191           assert paragraph_template_before.eql?(paragraph_template_after)
  192 
  193           # should not use cache
  194           doc = Asciidoctor::Document.new [], template_dir: template_dir, template_cache: false
  195           template_converter = doc.converter.find_converter('paragraph')
  196           paragraph_template_after = template_converter.templates['paragraph']
  197           refute_nil paragraph_template_after
  198           refute paragraph_template_before.eql?(paragraph_template_after)
  199         else
  200           assert_empty caches
  201         end
  202       ensure
  203         # clean up
  204         Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
  205       end
  206     end
  207 
  208     test 'should use custom cache to cache templates' do
  209       template_dir = fixture_path 'custom-backends/haml'
  210       Asciidoctor::PathResolver.new.system_path(File.join(template_dir, 'html5', 'block_paragraph.html.haml'), nil)
  211       caches = { scans: {}, templates: {} }
  212       doc = Asciidoctor::Document.new [], template_dir: template_dir, template_cache: caches
  213       doc.converter
  214       refute_empty caches[:scans]
  215       refute_empty caches[:templates]
  216       paragraph_template = caches[:templates].values.find {|t| File.basename(t.file) == 'block_paragraph.html.haml' }
  217       refute_nil paragraph_template
  218       assert_kind_of ::Tilt::HamlTemplate, paragraph_template
  219     end
  220 
  221     test 'should be able to disable template cache' do
  222       begin
  223         Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
  224         doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/haml'), template_cache: false
  225         doc.converter
  226         caches = Asciidoctor::Converter::TemplateConverter.caches
  227         assert caches.empty? || caches[:scans].empty?
  228         assert caches.empty? || caches[:templates].empty?
  229       ensure
  230         # clean up
  231         Asciidoctor::Converter::TemplateConverter.clear_caches if defined? Asciidoctor::Converter::TemplateConverter
  232       end
  233     end
  234 
  235     test 'should load ERB templates using ERBTemplate if eruby is not set' do
  236       input = %([.wrapper]\n--\nfoobar\n--)
  237       doc = Asciidoctor::Document.new input, template_dir: (fixture_path 'custom-backends/erb'), template_cache: false
  238       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
  239       %w(paragraph).each do |node_name|
  240         selected = doc.converter.find_converter node_name
  241         assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
  242         template = selected.templates[node_name]
  243         assert_kind_of Tilt::ERBTemplate, template
  244         refute_kind_of Tilt::ErubisTemplate, template
  245         assert_kind_of ::ERB, template.instance_variable_get('@engine')
  246         assert_equal %(block_#{node_name}.html.erb), File.basename(selected.templates[node_name].file)
  247       end
  248       # NOTE verify behavior of trim mode
  249       expected_output = <<~'EOS'.chop
  250       <div class="openblock wrapper">
  251       <div class="content">
  252       <div class="paragraph">
  253       <p>foobar</p>
  254       </div>
  255       </div>
  256       </div>
  257       EOS
  258       assert_equal expected_output, doc.convert
  259     end
  260 
  261     test 'should load ERB templates using ErubisTemplate if eruby is set to erubis' do
  262       doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/erb'), template_cache: false, eruby: 'erubis'
  263       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
  264       %w(paragraph).each do |node_name|
  265         selected = doc.converter.find_converter node_name
  266         assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
  267         template = selected.templates[node_name]
  268         assert_kind_of Tilt::ERBTemplate, template
  269         assert_kind_of Tilt::ErubisTemplate, template
  270         assert_kind_of ::Erubis::FastEruby, template.instance_variable_get('@engine')
  271         assert_equal %(block_#{node_name}.html.erb), File.basename(selected.templates[node_name].file)
  272       end
  273     end
  274 
  275     test 'should load Slim templates for default backend' do
  276       doc = Asciidoctor::Document.new [], template_dir: (fixture_path 'custom-backends/slim'), template_cache: false
  277       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
  278       %w(paragraph sidebar).each do |node_name|
  279         selected = doc.converter.find_converter node_name
  280         assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
  281         assert_kind_of Slim::Template, selected.templates[node_name]
  282         assert_equal %(block_#{node_name}.html.slim), File.basename(selected.templates[node_name].file)
  283       end
  284     end
  285 
  286     test 'should load Slim templates for docbook5 backend' do
  287       doc = Asciidoctor::Document.new [], backend: 'docbook5', template_dir: (fixture_path 'custom-backends/slim'), template_cache: false
  288       assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
  289       %w(paragraph).each do |node_name|
  290         selected = doc.converter.find_converter node_name
  291         assert_kind_of Asciidoctor::Converter::TemplateConverter, selected
  292         assert_kind_of Slim::Template, selected.templates[node_name]
  293         assert_equal %(block_#{node_name}.xml.slim), File.basename(selected.templates[node_name].file)
  294       end
  295     end
  296 
  297     test 'should use Slim templates in place of built-in templates' do
  298       input = <<~'EOS'
  299       = Document Title
  300       Author Name
  301 
  302       == Section One
  303 
  304       Sample paragraph
  305 
  306       .Related
  307       ****
  308       Sidebar content
  309       ****
  310       EOS
  311 
  312       output = convert_string_to_embedded input, template_dir: (fixture_path 'custom-backends/slim'), template_cache: false
  313       assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p', output, 1
  314       assert_xpath '//aside', output, 1
  315       assert_xpath '/*[@class="sect1"]/*[@class="sectionbody"]/p/following-sibling::aside', output, 1
  316       assert_xpath '//aside/header/h1[text()="Related"]', output, 1
  317       assert_xpath '//aside/header/following-sibling::p[text()="Sidebar content"]', output, 1
  318     end
  319   end
  320 
  321   context 'Custom converters' do
  322     test 'should derive backend traits for the given backend' do
  323       expected = { basebackend: 'dita', filetype: 'dita', outfilesuffix: '.dita' }
  324       actual = Asciidoctor::Converter.derive_backend_traits 'dita2'
  325       assert_equal expected, actual
  326     end
  327 
  328     test 'should use specified converter for current backend' do
  329       input = <<~'EOS'
  330       = Document Title
  331 
  332       preamble
  333 
  334       == Section
  335 
  336       content
  337       EOS
  338 
  339       class CustomHtmlConverterA
  340         def initialize *args; end
  341 
  342         def convert node, name = nil
  343           'document'
  344         end
  345       end
  346 
  347       doc = document_from_string input, converter: CustomHtmlConverterA
  348       assert_kind_of CustomHtmlConverterA, doc.converter
  349       assert_equal 'html', doc.attributes['filetype']
  350       assert 'document', doc.convert
  351     end
  352 
  353     test 'should use specified converter for specified backend' do
  354       input = <<~'EOS'
  355       = Document Title
  356 
  357       preamble
  358 
  359       == Section
  360 
  361       content
  362       EOS
  363 
  364       class CustomTextConverterA
  365         def initialize *args; end
  366 
  367         def convert node, name = nil
  368           'document'
  369         end
  370       end
  371 
  372       doc = document_from_string input, backend: 'text', converter: CustomTextConverterA
  373       assert_kind_of CustomTextConverterA, doc.converter
  374       assert_equal 'text', doc.attributes['filetype']
  375       assert 'document', doc.convert
  376     end
  377 
  378     test 'should get converter from specified converter factory' do
  379       input = <<~'EOS'
  380       = Document Title
  381 
  382       preamble
  383 
  384       == Section
  385 
  386       content
  387       EOS
  388 
  389       my_converter_class = Class.new Asciidoctor::Converter::Base do
  390         def convert_document node
  391           'document'
  392         end
  393       end
  394 
  395       converter_factory = Asciidoctor::Converter::CustomFactory.new 'html5' => my_converter_class
  396 
  397       doc = document_from_string input, converter_factory: converter_factory
  398       assert_kind_of my_converter_class, doc.converter
  399       assert_equal 'html', doc.attributes['filetype']
  400       assert 'document', doc.convert
  401     end
  402 
  403     test 'should allow converter to set htmlsyntax when basebackend is html' do
  404       input = 'image::sunset.jpg[]'
  405       converter = Asciidoctor::Converter.create 'html5', htmlsyntax: 'xml'
  406       doc = document_from_string input, converter: converter
  407       assert_equal converter, doc.converter
  408       assert_equal 'xml', (doc.attr 'htmlsyntax')
  409       output = doc.convert standalone: false
  410       assert_includes output, '<img src="sunset.jpg" alt="sunset"/>'
  411     end
  412 
  413     test 'should use converter registered for backend' do
  414       begin
  415         converters_before = Asciidoctor::Converter.converters
  416 
  417         class CustomConverterB
  418           include Asciidoctor::Converter
  419           register_for 'foobar'
  420           def initialize *args
  421             super
  422             basebackend 'text'
  423             filetype 'text'
  424             outfilesuffix '.fb'
  425           end
  426 
  427           def convert node, name = nil
  428             'foobar content'
  429           end
  430         end
  431 
  432         input = 'content'
  433         assert_equal CustomConverterB, (Asciidoctor::Converter.for 'foobar')
  434         converters = Asciidoctor::Converter.converters
  435         assert converters.size == converters_before.size + 1
  436         assert converters['foobar'] == CustomConverterB
  437         output = convert_string input, backend: 'foobar'
  438         assert 'foobar content', output
  439       ensure
  440         Asciidoctor::Converter.unregister_all
  441       end
  442     end
  443 
  444     test 'should be able to register converter using symbol' do
  445       begin
  446         converter = Class.new Asciidoctor::Converter::Base do
  447           register_for :foobaz
  448           def initialize *args
  449             super
  450             basebackend 'text'
  451             filetype 'text'
  452             outfilesuffix '.fb'
  453           end
  454         end
  455         assert_equal converter, (Asciidoctor::Converter.for 'foobaz')
  456       ensure
  457         Asciidoctor::Converter.unregister_all
  458       end
  459     end
  460 
  461     test 'should be able to register converter from converter class itself' do
  462       begin
  463         assert_nil Asciidoctor::Converter.for 'foobar'
  464 
  465         class AnotherCustomConverterB
  466           include Asciidoctor::Converter
  467         end
  468 
  469         AnotherCustomConverterB.register_for 'foobar'
  470         assert_equal AnotherCustomConverterB, (Asciidoctor::Converter.for 'foobar')
  471       ensure
  472         Asciidoctor::Converter.unregister_all
  473       end
  474     end
  475 
  476     test 'should map handles? method on converter to respond_to? implementation by default' do
  477       class CustomConverterC
  478         include Asciidoctor::Converter
  479         def convert_paragraph node
  480           'paragraph'
  481         end
  482       end
  483 
  484       converter = CustomConverterC.new 'myhtml'
  485       assert_respond_to converter, :handles?
  486       assert converter.handles?(:convert_paragraph)
  487     end
  488 
  489     test 'should not configure converter to support templates by default' do
  490       begin
  491         class CustomConverterD
  492           include Asciidoctor::Converter
  493           register_for 'myhtml'
  494 
  495           def convert node, transform = nil, opts = nil
  496             transform ||= node.node_name
  497             send transform, node
  498           end
  499 
  500           def document node
  501             ['<!DOCTYPE html>', '<html>', '<body>', node.content, '</body>', '</html>'] * %(\n)
  502           end
  503 
  504           def paragraph node
  505             ['<div class="paragraph">', %(<p>#{node.content}</p>), '</div>'] * %(\n)
  506           end
  507         end
  508 
  509         input = 'paragraph'
  510         doc = document_from_string input, backend: 'myhtml', template_dir: (fixture_path 'custom-backends/slim/html5'), template_cache: false
  511         assert_kind_of CustomConverterD, doc.converter
  512         refute doc.converter.supports_templates?
  513         output = doc.convert
  514         assert_xpath '//*[@class="paragraph"]/p[text()="paragraph"]', output, 1
  515       ensure
  516         Asciidoctor::Converter.unregister_all
  517       end
  518     end
  519 
  520     test 'should wrap converter in composite converter with template converter if it declares that it supports templates' do
  521       begin
  522         class CustomConverterE < Asciidoctor::Converter::Base
  523           register_for 'myhtml'
  524 
  525           def initialize *args
  526             super
  527             supports_templates
  528           end
  529 
  530           def convert node, transform = nil, opts = nil
  531             transform ||= node.node_name
  532             send transform, node
  533           end
  534 
  535           alias handles? respond_to?
  536 
  537           def document node
  538             ['<!DOCTYPE html>', '<html>', '<body>', node.content, '</body>', '</html>'] * %(\n)
  539           end
  540 
  541           def paragraph node
  542             ['<div class="paragraph">', %(<p>#{node.content}</p>), '</div>'] * %(\n)
  543           end
  544         end
  545 
  546         input = 'paragraph'
  547         doc = document_from_string input, backend: 'myhtml', template_dir: (fixture_path 'custom-backends/slim/html5'), template_cache: false
  548         assert_kind_of Asciidoctor::Converter::CompositeConverter, doc.converter
  549         output = doc.convert
  550         assert_xpath '//*[@class="paragraph"]/p[text()="paragraph"]', output, 0
  551         assert_xpath '//body/p[text()="paragraph"]', output, 1
  552       ensure
  553         Asciidoctor::Converter.unregister_all
  554       end
  555     end
  556 
  557     test 'should map Factory.new to DefaultFactoryProxy constructor by default' do
  558       assert_equal (Asciidoctor::Converter.for 'html5'), (Asciidoctor::Converter::Factory.new.for 'html5')
  559     end
  560 
  561     test 'should map Factory.new to CustomFactory constructor if proxy keyword arg is false' do
  562       assert_nil (Asciidoctor::Converter::Factory.new proxy_default: false).for 'html5'
  563     end
  564 
  565     test 'should default to catch all converter' do
  566       begin
  567         class CustomConverterF
  568           include Asciidoctor::Converter
  569           register_for '*'
  570           def convert node, name = nil
  571             'foobaz content'
  572           end
  573         end
  574 
  575         input = 'content'
  576         assert_equal CustomConverterF, (Asciidoctor::Converter.for 'all')
  577         assert_equal CustomConverterF, (Asciidoctor::Converter.for 'whatever')
  578         refute_equal CustomConverterF, (Asciidoctor::Converter.for 'html5')
  579         converters = Asciidoctor::Converter.converters
  580         assert_nil converters['*']
  581         assert_equal CustomConverterF, (Asciidoctor::Converter.send :catch_all)
  582         output = convert_string input, backend: 'foobaz'
  583         assert 'foobaz content', output
  584       ensure
  585         Asciidoctor::Converter.unregister_all
  586       end
  587     end
  588 
  589     test 'should use catch all converter from custom factory only if no other converter matches' do
  590       class FooConverter < Asciidoctor::Converter::Base; end
  591       class CatchAllConverter < Asciidoctor::Converter::Base; end
  592 
  593       factory = Asciidoctor::Converter::CustomFactory.new 'foo' => FooConverter, '*' => CatchAllConverter
  594       assert_equal FooConverter, (factory.for 'foo')
  595       assert_equal CatchAllConverter, (factory.for 'nada')
  596       assert_equal CatchAllConverter, (factory.for 'html5')
  597     end
  598 
  599     test 'should prefer catch all converter from proxy over statically registered catch all converter' do
  600       begin
  601         class StaticCatchAllConverter < Asciidoctor::Converter::Base
  602           register_for '*'
  603         end
  604 
  605         class LocalCatchAllConverter < Asciidoctor::Converter::Base; end
  606 
  607         factory = Asciidoctor::Converter::DefaultFactoryProxy.new '*' => LocalCatchAllConverter
  608         assert_equal LocalCatchAllConverter, (factory.for 'foobar')
  609         refute_equal LocalCatchAllConverter, (factory.for 'html5')
  610         refute_equal StaticCatchAllConverter, (factory.for 'html5')
  611       ensure
  612         Asciidoctor::Converter.unregister_all
  613       end
  614     end
  615 
  616     test 'should prefer converter in proxy with same name as provided converter' do
  617       class MyHtml5Converter < Asciidoctor::Converter::Base; end
  618       factory = Asciidoctor::Converter::DefaultFactoryProxy.new 'html5' => MyHtml5Converter
  619       assert_equal MyHtml5Converter, (factory.for 'html5')
  620     end
  621 
  622     test 'should allow nil to be registered as converter' do
  623       factory = Asciidoctor::Converter::DefaultFactoryProxy.new 'html5' => nil
  624       assert_nil factory.for 'html5'
  625     end
  626 
  627     test 'should create a new custom factory when Converter::Factory.new is invoked' do
  628       class MyConverter < Asciidoctor::Converter::Base; end
  629       factory = Asciidoctor::Converter::Factory.new 'mine' => MyConverter
  630       assert_kind_of Asciidoctor::Converter::CustomFactory, factory
  631       assert_equal MyConverter, (factory.for 'mine')
  632     end
  633 
  634     test 'should delegate to method on HTML 5 converter with convert_ prefix if called without prefix' do
  635       doc = document_from_string 'paragraph'
  636       result = doc.converter.paragraph doc.blocks[0]
  637       assert_css 'p', result, 1
  638     end
  639 
  640     test 'can call read_svg_contents on built-in HTML5 converter; should remove markup prior the root svg element' do
  641       doc = document_from_string 'image::circle.svg[]', base_dir: fixturedir
  642       result = doc.converter.read_svg_contents doc.blocks[0], 'circle.svg'
  643       refute_nil result
  644       assert result.start_with? '<svg'
  645     end
  646   end
  647 end