# frozen_string_literal: true require_relative 'test_helper' context 'API' do context 'Load' do test 'should load input file' do sample_input_path = fixture_path('sample.adoc') doc = File.open(sample_input_path) {|file| Asciidoctor.load file, safe: Asciidoctor::SafeMode::SAFE } assert_equal 'Document Title', doc.doctitle assert_equal File.expand_path(sample_input_path), doc.attr('docfile') assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir') assert_equal '.adoc', doc.attr('docfilesuffix') end test 'should load input file from filename' do sample_input_path = fixture_path('sample.adoc') doc = Asciidoctor.load_file(sample_input_path, safe: Asciidoctor::SafeMode::SAFE) assert_equal 'Document Title', doc.doctitle assert_equal File.expand_path(sample_input_path), doc.attr('docfile') assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir') assert_equal '.adoc', doc.attr('docfilesuffix') end test 'should load input file with alternate file extension' do sample_input_path = fixture_path 'sample-alt-extension.asciidoc' doc = Asciidoctor.load_file sample_input_path, safe: :safe assert_equal 'Document Title', doc.doctitle assert_equal File.expand_path(sample_input_path), doc.attr('docfile') assert_equal File.expand_path(File.dirname(sample_input_path)), doc.attr('docdir') assert_equal '.asciidoc', doc.attr('docfilesuffix') end test 'should coerce encoding of file to UTF-8' do old_external = Encoding.default_external old_internal = Encoding.default_internal old_verbose = $VERBOSE begin $VERBOSE = nil # disable warnings since we have to modify constants input_path = fixture_path 'encoding.adoc' Encoding.default_external = Encoding.default_internal = Encoding::IBM437 output = Asciidoctor.convert_file input_path, to_file: false, safe: :safe assert_equal Encoding::UTF_8, output.encoding assert_includes output, 'Romé' ensure Encoding.default_external = old_external Encoding.default_internal = old_internal $VERBOSE = old_verbose end end test 'should not load file with unrecognized encoding' do begin tmp_input = Tempfile.new %w(test- .adoc), encoding: Encoding::IBM437 # NOTE using a character whose code differs between UTF-8 and IBM437 tmp_input.write %(ƒ\n) tmp_input.close exception = assert_raises ArgumentError do Asciidoctor.load_file tmp_input.path, safe: :safe end expected_message = 'Failed to load AsciiDoc document - source is either binary or contains invalid Unicode data' assert_includes exception.message, expected_message ensure tmp_input.close! end end test 'should not load invalid file' do sample_input_path = fixture_path('hello-asciidoctor.pdf') exception = assert_raises ArgumentError do Asciidoctor.load_file(sample_input_path, safe: Asciidoctor::SafeMode::SAFE) end expected_message = 'Failed to load AsciiDoc document - source is either binary or contains invalid Unicode data' assert_includes exception.message, expected_message # verify we have the correct backtrace (should be at least in the first 5 lines) assert_match(/reader\.rb.*prepare_lines/, exception.backtrace[0..4].join(?\n)) end test 'should convert filename that contains non-ASCII characters independent of default encodings' do old_external = Encoding.default_external old_internal = Encoding.default_internal old_verbose = $VERBOSE begin $VERBOSE = nil # disable warnings since we have to modify constants tmp_input = Tempfile.new %w(test-UTF8- .adoc) tmp_input.write %(UTF8\n) tmp_input.close Encoding.default_external = Encoding.default_internal = Encoding::IBM437 tmp_output = tmp_input.path.sub '.adoc', '.html' Asciidoctor.convert_file tmp_input.path, safe: :safe, attributes: 'linkcss !copycss' assert File.exist? tmp_output output = File.read tmp_output, mode: 'rb', encoding: 'utf-8:utf-8' assert_equal ::Encoding::UTF_8, output.encoding refute_empty output assert_includes output, 'UTF8' ensure tmp_input.close! FileUtils.rm_f tmp_output Encoding.default_external = old_external Encoding.default_internal = old_internal $VERBOSE = old_verbose end end test 'should load input IO' do input = StringIO.new <<~'EOS' Document Title ============== preamble EOS doc = Asciidoctor.load(input, safe: Asciidoctor::SafeMode::SAFE) assert_equal 'Document Title', doc.doctitle refute doc.attr?('docfile') assert_equal doc.base_dir, doc.attr('docdir') end test 'should load input string' do input = <<~'EOS' Document Title ============== preamble EOS doc = Asciidoctor.load(input, safe: Asciidoctor::SafeMode::SAFE) assert_equal 'Document Title', doc.doctitle refute doc.attr?('docfile') assert_equal doc.base_dir, doc.attr('docdir') end test 'should load input string array' do input = <<~'EOS' Document Title ============== preamble EOS doc = Asciidoctor.load(input.lines, safe: Asciidoctor::SafeMode::SAFE) assert_equal 'Document Title', doc.doctitle refute doc.attr?('docfile') assert_equal doc.base_dir, doc.attr('docdir') end test 'should load nil input' do doc = Asciidoctor.load nil, safe: :safe refute_nil doc assert_empty doc.blocks end test 'should accept attributes as array' do # NOTE there's a tab character before idseparator doc = Asciidoctor.load('text', attributes: %w(toc sectnums source-highlighter=coderay idprefix idseparator=-)) assert_kind_of Hash, doc.attributes assert doc.attr?('toc') assert_equal '', doc.attr('toc') assert doc.attr?('sectnums') assert_equal '', doc.attr('sectnums') assert doc.attr?('source-highlighter') assert_equal 'coderay', doc.attr('source-highlighter') assert doc.attr?('idprefix') assert_equal '', doc.attr('idprefix') assert doc.attr?('idseparator') assert_equal '-', doc.attr('idseparator') end test 'should accept attributes as empty array' do doc = Asciidoctor.load('text', attributes: []) assert_kind_of Hash, doc.attributes end test 'should accept attributes as string' do doc = Asciidoctor.load 'text', attributes: %(toc sectnums\nsource-highlighter=coderay\nidprefix\nidseparator=-) assert_kind_of Hash, doc.attributes assert doc.attr?('toc') assert_equal '', doc.attr('toc') assert doc.attr?('sectnums') assert_equal '', doc.attr('sectnums') assert doc.attr?('source-highlighter') assert_equal 'coderay', doc.attr('source-highlighter') assert doc.attr?('idprefix') assert_equal '', doc.attr('idprefix') assert doc.attr?('idseparator') assert_equal '-', doc.attr('idseparator') end test 'should accept values containing spaces in attributes string' do doc = Asciidoctor.load('text', attributes: %(idprefix idseparator=- note-caption=Note\\ to\\\tself toc)) assert_kind_of Hash, doc.attributes assert doc.attr?('idprefix') assert_equal '', doc.attr('idprefix') assert doc.attr?('idseparator') assert_equal '-', doc.attr('idseparator') assert doc.attr?('note-caption') assert_equal "Note to\tself", doc.attr('note-caption') end test 'should accept attributes as empty string' do doc = Asciidoctor.load('text', attributes: '') assert_kind_of Hash, doc.attributes end test 'should accept attributes as nil' do doc = Asciidoctor.load('text', attributes: nil) assert_kind_of Hash, doc.attributes end test 'should accept attributes if hash like' do class Hashish def initialize @table = { 'toc' => '' } end def keys @table.keys end def [](key) @table[key] end end doc = Asciidoctor.load('text', attributes: Hashish.new) assert_kind_of Hash, doc.attributes assert doc.attributes.has_key?('toc') end test 'should not expand value of docdir attribute if specified via API' do docdir = 'virtual/directory' doc = document_from_string '', safe: :safe, attributes: { 'docdir' => docdir } assert_equal docdir, (doc.attr 'docdir') assert_equal docdir, doc.base_dir end test 'converts block to output format when convert is called' do doc = Asciidoctor.load 'paragraph text' expected = <<~'EOS'.chop
paragraph text
'
end
test 'can substitute an extended syntax highlighter factory implementation using the :syntax_highlighters option' do
input = <<~'EOS'
[source,ruby]
----
puts 'Hello, World!'
----
EOS
syntax_hl_factory_class = Class.new do
include Asciidoctor::SyntaxHighlighter::DefaultFactory
def for name
super 'highlight.js'
end
end
doc = Asciidoctor.load input, safe: :safe, syntax_highlighter_factory: syntax_hl_factory_class.new, attributes: { 'source-highlighter' => 'coderay' }
refute_nil doc.syntax_highlighter
output = doc.convert
refute_includes output, 'CodeRay'
assert_includes output, 'hljs'
end
end
context 'Convert' do
test 'render_file is aliased to convert_file' do
assert_equal Asciidoctor.method(:convert_file), Asciidoctor.method(:render_file)
end
test 'render is aliased to convert' do
assert_equal Asciidoctor.method(:convert), Asciidoctor.method(:render)
end
test 'should convert source document to standalone document string when to_file is false and standalone is true' do
sample_input_path = fixture_path('sample.adoc')
output = Asciidoctor.convert_file sample_input_path, standalone: true, to_file: false
refute_empty output
assert_xpath '/html', output, 1
assert_xpath '/html/head', output, 1
assert_xpath '/html/body', output, 1
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
end
test 'should convert source document to standalone document string when to_file is false and header_footer is true' do
sample_input_path = fixture_path('sample.adoc')
output = Asciidoctor.convert_file sample_input_path, header_footer: true, to_file: false
refute_empty output
assert_xpath '/html', output, 1
assert_xpath '/html/head', output, 1
assert_xpath '/html/body', output, 1
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
end
test 'lines in output should be separated by line feed' do
sample_input_path = fixture_path('sample.adoc')
output = Asciidoctor.convert_file sample_input_path, standalone: true, to_file: false
refute_empty output
lines = output.split("\n")
assert_equal lines.size, output.split(/\r\n|\r|\n/).size
raw_lengths = lines.map(&:length)
trimmed_lengths = lines.map {|line| line.rstrip.length }
assert_equal raw_lengths, trimmed_lengths
end
test 'should accept attributes as array' do
sample_input_path = fixture_path('sample.adoc')
output = Asciidoctor.convert_file sample_input_path, attributes: %w(sectnums idprefix idseparator=-), to_file: false
assert_css '#section-a', output, 1
end
test 'should accept attributes as string' do
sample_input_path = fixture_path('sample.adoc')
output = Asciidoctor.convert_file sample_input_path, attributes: 'sectnums idprefix idseparator=-', to_file: false
assert_css '#section-a', output, 1
end
test 'should link to default stylesheet by default when safe mode is SECURE or greater' do
sample_input_path = fixture_path('basic.adoc')
output = Asciidoctor.convert_file sample_input_path, standalone: true, to_file: false
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
end
test 'should embed default stylesheet by default if SafeMode is less than SECURE' do
input = <<~'EOS'
= Document Title
text
EOS
output = Asciidoctor.convert input, safe: Asciidoctor::SafeMode::SERVER, standalone: true
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
styles = stylenode.content
refute_nil styles
refute_empty styles.strip
end
test 'should not allow linkcss be unset from document if SafeMode is SECURE or greater' do
input = <<~'EOS'
= Document Title
:linkcss!:
text
EOS
output = Asciidoctor.convert input, standalone: true
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 1
end
test 'should embed default stylesheet if linkcss is unset from API and SafeMode is SECURE or greater' do
input = <<~'EOS'
= Document Title
text
EOS
#[{ 'linkcss!' => '' }, { 'linkcss' => nil }, { 'linkcss' => false }].each do |attrs|
[{ 'linkcss!' => '' }, { 'linkcss' => nil }].each do |attrs|
output = Asciidoctor.convert input, standalone: true, attributes: attrs
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 1
assert_css 'html:root > head > link[rel="stylesheet"][href="./asciidoctor.css"]', output, 0
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
styles = stylenode.content
refute_nil styles
refute_empty styles.strip
end
end
test 'should embed default stylesheet if safe mode is less than SECURE and linkcss is unset from API' do
sample_input_path = fixture_path('basic.adoc')
output = Asciidoctor.convert_file sample_input_path, standalone: true, to_file: false,
safe: Asciidoctor::SafeMode::SAFE, attributes: { 'linkcss!' => '' }
assert_css 'html:root > head > style', output, 1
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
styles = stylenode.content
refute_nil styles
refute_empty styles.strip
end
test 'should not link to stylesheet if stylesheet is unset' do
input = <<~'EOS'
= Document Title
text
EOS
output = Asciidoctor.convert input, standalone: true, attributes: { 'stylesheet!' => '' }
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
assert_css 'html:root > head > link[rel="stylesheet"]', output, 0
end
test 'should link to custom stylesheet if specified in stylesheet attribute' do
input = <<~'EOS'
= Document Title
text
EOS
output = Asciidoctor.convert input, standalone: true, attributes: { 'stylesheet' => './custom.css' }
assert_css 'html:root > head > link[rel="stylesheet"][href^="https://fonts.googleapis.com"]', output, 0
assert_css 'html:root > head > link[rel="stylesheet"][href="./custom.css"]', output, 1
output = Asciidoctor.convert input, standalone: true, attributes: { 'stylesheet' => 'file:///home/username/custom.css' }
assert_css 'html:root > head > link[rel="stylesheet"][href="file:///home/username/custom.css"]', output, 1
end
test 'should resolve custom stylesheet relative to stylesdir' do
input = <<~'EOS'
= Document Title
text
EOS
output = Asciidoctor.convert input, standalone: true, attributes: { 'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets' }
assert_css 'html:root > head > link[rel="stylesheet"][href="./stylesheets/custom.css"]', output, 1
end
test 'should resolve custom stylesheet to embed relative to stylesdir' do
sample_input_path = fixture_path('basic.adoc')
output = Asciidoctor.convert_file sample_input_path, standalone: true, safe: Asciidoctor::SafeMode::SAFE, to_file: false,
attributes: { 'stylesheet' => 'custom.css', 'stylesdir' => './stylesheets', 'linkcss!' => '' }
stylenode = xmlnodes_at_css 'html:root > head > style', output, 1
styles = stylenode.content
refute_nil styles
refute_empty styles.strip
end
test 'should convert source file and write result to adjacent file by default' do
sample_input_path = fixture_path('sample.adoc')
sample_output_path = fixture_path('sample.html')
begin
Asciidoctor.convert_file sample_input_path
assert File.exist?(sample_output_path)
output = File.read(sample_output_path)
refute_empty output
assert_xpath '/html', output, 1
assert_xpath '/html/head', output, 1
assert_xpath '/html/body', output, 1
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
ensure
FileUtils.rm(sample_output_path)
end
end
test 'should convert source file and write to specified file' do
sample_input_path = fixture_path('sample.adoc')
sample_output_path = fixture_path('result.html')
begin
Asciidoctor.convert_file sample_input_path, to_file: sample_output_path
assert File.exist?(sample_output_path)
output = File.read(sample_output_path)
refute_empty output
assert_xpath '/html', output, 1
assert_xpath '/html/head', output, 1
assert_xpath '/html/body', output, 1
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
ensure
FileUtils.rm(sample_output_path)
end
end
test 'should convert source file and write to specified file in base_dir' do
sample_input_path = fixture_path('sample.adoc')
sample_output_path = fixture_path('result.html')
fixture_dir = fixture_path('')
begin
Asciidoctor.convert_file sample_input_path, to_file: 'result.html', base_dir: fixture_dir
assert File.exist?(sample_output_path)
output = File.read(sample_output_path)
refute_empty output
assert_xpath '/html', output, 1
assert_xpath '/html/head', output, 1
assert_xpath '/html/body', output, 1
assert_xpath '/html/head/title[text() = "Document Title"]', output, 1
assert_xpath '/html/body/*[@id="header"]/h1[text() = "Document Title"]', output, 1
rescue => e
flunk e.message
ensure
FileUtils.rm(sample_output_path, force: true)
end
end
test 'in_place option is ignored when to_file is specified' do
sample_input_path = fixture_path('sample.adoc')
sample_output_path = fixture_path('result.html')
begin
Asciidoctor.convert_file sample_input_path, to_file: sample_output_path, in_place: true
assert File.exist?(sample_output_path)
ensure
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
end
end
test 'in_place option is ignored when to_dir is specified' do
sample_input_path = fixture_path('sample.adoc')
sample_output_path = fixture_path('sample.html')
begin
Asciidoctor.convert_file sample_input_path, to_dir: File.dirname(sample_output_path), in_place: true
assert File.exist?(sample_output_path)
ensure
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
end
end
test 'should set outfilesuffix to match file extension of target file' do
sample_input = '{outfilesuffix}'
sample_output_path = fixture_path('result.htm')
begin
Asciidoctor.convert sample_input, to_file: sample_output_path
assert File.exist?(sample_output_path)
output = File.read(sample_output_path)
refute_empty output
assert_includes output, '.htm
'
ensure
FileUtils.rm(sample_output_path)
end
end
test 'should respect outfilesuffix soft set from API' do
sample_input_path = fixture_path('sample.adoc')
sample_output_path = fixture_path('sample.htm')
begin
Asciidoctor.convert_file sample_input_path, to_dir: (File.dirname sample_input_path), attributes: { 'outfilesuffix' => '.htm@' }
assert File.exist?(sample_output_path)
ensure
FileUtils.rm(sample_output_path)
end
end
test 'output should be relative to to_dir option' do
sample_input_path = fixture_path('sample.adoc')
output_dir = File.join(File.dirname(sample_input_path), 'test_output')
Dir.mkdir output_dir if !File.exist? output_dir
sample_output_path = File.join(output_dir, 'sample.html')
begin
Asciidoctor.convert_file sample_input_path, to_dir: output_dir
assert File.exist? sample_output_path
ensure
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
FileUtils.rmdir output_dir
end
end
test 'missing directories should be created if mkdirs is enabled' do
sample_input_path = fixture_path('sample.adoc')
output_dir = File.join(File.join(File.dirname(sample_input_path), 'test_output'), 'subdir')
sample_output_path = File.join(output_dir, 'sample.html')
begin
Asciidoctor.convert_file sample_input_path, to_dir: output_dir, mkdirs: true
assert File.exist? sample_output_path
ensure
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
FileUtils.rmdir output_dir
FileUtils.rmdir File.dirname(output_dir)
end
end
# TODO need similar test for when to_dir is specified
test 'should raise exception if an attempt is made to overwrite input file' do
sample_input_path = fixture_path('sample.adoc')
assert_raises IOError do
Asciidoctor.convert_file sample_input_path, attributes: { 'outfilesuffix' => '.adoc' }
end
end
test 'to_file should be relative to to_dir when both given' do
sample_input_path = fixture_path('sample.adoc')
base_dir = File.dirname(sample_input_path)
sample_rel_output_path = File.join('test_output', 'result.html')
output_dir = File.dirname(File.join(base_dir, sample_rel_output_path))
Dir.mkdir output_dir if !File.exist? output_dir
sample_output_path = File.join(base_dir, sample_rel_output_path)
begin
Asciidoctor.convert_file sample_input_path, to_dir: base_dir, to_file: sample_rel_output_path
assert File.exist? sample_output_path
ensure
FileUtils.rm(sample_output_path) if File.exist? sample_output_path
FileUtils.rmdir output_dir
end
end
test 'should not modify options argument' do
options = {
safe: Asciidoctor::SafeMode::SAFE,
to_file: false,
}
options.freeze
sample_input_path = fixture_path('sample.adoc')
begin
Asciidoctor.convert_file sample_input_path, options
rescue
flunk %(options argument should not be modified)
end
end
test 'should set to_dir option to parent directory of specified output file' do
sample_input_path = fixture_path 'basic.adoc'
sample_output_path = fixture_path 'basic.html'
begin
doc = Asciidoctor.convert_file sample_input_path, to_file: sample_output_path
assert_equal File.dirname(sample_output_path), doc.options[:to_dir]
ensure
FileUtils.rm(sample_output_path)
end
end
test 'should set to_dir option to parent directory of specified output directory and file' do
sample_input_path = fixture_path 'basic.adoc'
sample_output_path = fixture_path 'basic.html'
fixture_base_path = File.dirname sample_output_path
fixture_parent_path = File.dirname fixture_base_path
sample_output_relpath = File.join 'fixtures', 'basic.html'
begin
doc = Asciidoctor.convert_file sample_input_path, to_dir: fixture_parent_path, to_file: sample_output_relpath
assert_equal fixture_base_path, doc.options[:to_dir]
ensure
FileUtils.rm(sample_output_path)
end
end
test 'timings are recorded for each step' do
sample_input_path = fixture_path 'asciidoc_index.txt'
Asciidoctor.convert_file sample_input_path, timings: (timings = Asciidoctor::Timings.new), to_file: false
refute_equal '0.00000', '%05.5f' % timings.read_parse.to_f
refute_equal '0.00000', '%05.5f' % timings.convert.to_f
refute_equal timings.read_parse, timings.total
end
test 'can override syntax highlighter using syntax_highlighters option' do
syntax_hl = Class.new Asciidoctor::SyntaxHighlighter::Base do
def highlight?
true
end
def highlight node, source, lang, opts
'highlighted'
end
end
input = <<~'EOS'
[source,ruby]
----
puts 'Hello, World!'
----
EOS
output = Asciidoctor.convert input, safe: :safe, syntax_highlighters: { 'coderay' => syntax_hl }, attributes: { 'source-highlighter' => 'coderay' }
assert_css 'pre.highlight > code[data-lang="ruby"]', output, 1
assert_xpath '//pre[@class="coderay highlight"]/code[text()="highlighted"]', output, 1
end
end
context 'AST' do
test 'with no author' do
input = <<~'EOS'
= Getting Real: The Smarter, Faster, Easier Way to Build a Successful Web Application
Getting Real details the business, design, programming, and marketing principles of 37signals.
EOS
doc = document_from_string input
assert_equal 0, doc.authors.size
end
test 'with one author' do
input = <<~'EOS'
= Getting Real: The Smarter, Faster, Easier Way to Build a Successful Web Application
David Heinemeier Hansson
Getting Real details the business, design, programming, and marketing principles of 37signals.
EOS
doc = document_from_string input
authors = doc.authors
assert_equal 1, authors.size
author_1 = authors[0]
assert_equal 'david@37signals.com', author_1.email
assert_equal 'David Heinemeier Hansson', author_1.name
assert_equal 'David', author_1.firstname
assert_equal 'Heinemeier', author_1.middlename
assert_equal 'Hansson', author_1.lastname
assert_equal 'DHH', author_1.initials
end
test 'with two authors' do
input = <<~'EOS'
= Getting Real: The Smarter, Faster, Easier Way to Build a Successful Web Application
David Heinemeier Hansson ; Jason Fried
Getting Real details the business, design, programming, and marketing principles of 37signals.
EOS
doc = document_from_string input
authors = doc.authors
assert_equal 2, authors.size
author_1 = authors[0]
assert_equal 'david@37signals.com', author_1.email
assert_equal 'David Heinemeier Hansson', author_1.name
assert_equal 'David', author_1.firstname
assert_equal 'Heinemeier', author_1.middlename
assert_equal 'Hansson', author_1.lastname
assert_equal 'DHH', author_1.initials
author_2 = authors[1]
assert_equal 'jason@37signals.com', author_2.email
assert_equal 'Jason Fried', author_2.name
assert_equal 'Jason', author_2.firstname
assert_nil author_2.middlename
assert_equal 'Fried', author_2.lastname
assert_equal 'JF', author_2.initials
end
test 'with authors as attributes' do
input = <<~'EOS'
= Getting Real: The Smarter, Faster, Easier Way to Build a Successful Web Application
:author_1: David Heinemeier Hansson
:email_1: david@37signals.com
:author_2: Jason Fried
:email_2: jason@37signals.com
Getting Real details the business, design, programming, and marketing principles of 37signals.
EOS
doc = document_from_string input
authors = doc.authors
assert_equal 2, authors.size
author_1 = authors[0]
assert_equal 'david@37signals.com', author_1.email
assert_equal 'David Heinemeier Hansson', author_1.name
assert_equal 'David', author_1.firstname
assert_equal 'Heinemeier', author_1.middlename
assert_equal 'Hansson', author_1.lastname
assert_equal 'DHH', author_1.initials
author_2 = authors[1]
assert_equal 'jason@37signals.com', author_2.email
assert_equal 'Jason Fried', author_2.name
assert_equal 'Jason', author_2.firstname
assert_nil author_2.middlename
assert_equal 'Fried', author_2.lastname
assert_equal 'JF', author_2.initials
end
test 'should not crash if nil cell text is passed to Cell constructor' do
input = <<~'EOS'
|===
|a
|===
EOS
table = (document_from_string input).blocks[0]
cell = Asciidoctor::Table::Cell.new table.rows.body[0][0].column, nil, {}
refute cell.style
assert_same Asciidoctor::AbstractNode::NORMAL_SUBS, cell.subs
assert_equal '', cell.text
end
test 'should set option on node when set_option is called' do
input = <<~'EOS'
. three
. two
. one
EOS
block = (document_from_string input).blocks[0]
block.set_option('reversed')
assert block.option? 'reversed'
assert_equal '', block.attributes['reversed-option']
end
test 'should append option to existing options' do
input = <<~'EOS'
[%fancy]
. three
. two
. one
EOS
block = (document_from_string input).blocks[0]
block.set_option('reversed')
assert block.option? 'fancy'
assert block.option? 'reversed'
end
test 'should not append option if option is already set' do
input = <<~'EOS'
[%reversed]
. three
. two
. one
EOS
block = (document_from_string input).blocks[0]
refute block.set_option('reversed')
assert_equal '', block.attributes['reversed-option']
end
test 'should return set of option names' do
input = <<~'EOS'
[%compact%reversed]
. three
. two
. one
EOS
block = (document_from_string input).blocks[0]
assert_equal %w(compact reversed).to_set, block.options
end
test 'table column should not be a block or inline' do
input = <<~'EOS'
|===
|a
|===
EOS
col = (document_from_string input).blocks[0].columns[0]
refute col.block?
refute col.inline?
end
test 'table cell should be a block' do
input = <<~'EOS'
|===
|a
|===
EOS
cell = (document_from_string input).blocks[0].rows.body[0][0]
assert_kind_of ::Asciidoctor::AbstractBlock, cell
assert cell.block?
refute cell.inline?
end
test 'next_adjacent_block should return next block' do
input = <<~'EOS'
first
second
EOS
doc = document_from_string input
assert_equal doc.blocks[1], doc.blocks[0].next_adjacent_block
end
test 'next_adjacent_block should return next sibling of parent if called on last sibling' do
input = <<~'EOS'
--
first
--
second
EOS
doc = document_from_string input
assert_equal doc.blocks[1], doc.blocks[0].blocks[0].next_adjacent_block
end
test 'next_adjacent_block should return next sibling of list if called on last item' do
input = <<~'EOS'
* first
second
EOS
doc = document_from_string input
assert_equal doc.blocks[1], doc.blocks[0].blocks[0].next_adjacent_block
end
test 'next_adjacent_block should return next item in dlist if called on last block of list item' do
input = <<~'EOS'
first::
desc
+
more desc
second::
desc
EOS
doc = document_from_string input
assert_equal doc.blocks[0].items[1], doc.blocks[0].items[0][1].blocks[0].next_adjacent_block
end
end
end