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
|
require_relative 'spec_helper'
require 'asciidoctor/include_ext/include_processor'
require 'webrick'
FIXTURES_DIR = File.expand_path('fixtures', __dir__)
describe 'Integration tests' do
subject(:output) { Asciidoctor.convert(input, options) }
let(:input) { '' } # this is modified in #given
let(:processor) { Asciidoctor::IncludeExt::IncludeProcessor.new }
let(:options) {
processor_ = processor
{
safe: :safe,
header_footer: false,
base_dir: FIXTURES_DIR,
extensions: proc { include_processor processor_ },
}
}
before do
# XXX: Ugly hack to get rid of rspec-mocks' warnings about resetting
# frozen object; https://github.com/rspec/rspec-mocks/issues/1190.
processor.define_singleton_method(:freeze) { self }
# Make sure that Asciidoctor really calls our processor.
expect(processor).to receive(:process).at_least(:once).and_call_original
end
describe 'include::[] directive' do
it 'is replaced by a link when safe mode is default' do
given 'include::include-file.adoc[]', safe: nil
should match /<a[^>]+href="include-file.adoc"/
should_not match /included content/
end
it 'is resolved when safe mode is less than SECURE' do
given 'include::include-file.adoc[]'
should match /included content/
should_not match /<a[^>]+href="include-file\.adoc"/
end
it 'nested includes are resolved with relative paths' do
given 'include::a/include-1.adoc[]'
expect( output.scan(/[^>]*include \w+/) ).to eq [
'begin of include 1', 'include 2a', 'begin of include 2b', 'include 3',
'end of include 2b', 'end of include 1'
]
end
it 'is replaced by a warning when target is not found' do
given <<~ADOC
include::no-such-file.adoc[]
trailing content
ADOC
should match /unresolved/i
should match /trailing content/
end
it 'is skipped when target is not found and optional option is set' do
given <<~ADOC
include::no-such-file.adoc[opts=optional]
trailing content
ADOC
should match /trailing content/
should_not match /unresolved/i
end
it 'is replaced by a link when target is an URI and attribute allow-uri-read is not set' do
using_test_webserver do |host, port|
target = "http://#{host}:#{port}/hello.json"
given "include::#{target}[]"
should match /<a[^>]*href="#{target}"/
should_not match /\{"message": "Hello, world!"\}/
end
end
it 'retrieves content from URI target when allow-uri-read is set' do
using_test_webserver do |host, port|
given "include::http://#{host}:#{port}/hello.json[]",
attributes: { 'allow-uri-read' => '' }
should match /\{"message": "Hello, world!"\}/
should_not match /unresolved/i
end
end
it 'supports line selection' do
given 'include::include-file.adoc[lines=1;3..4;6..-1]'
%w[1 3 4 6 7 8].each do |n|
should match /line #{n} of included content/
end
should match /last line/
should_not match /line 2/
should_not match /line 5/
end
it 'supports tagged selection' do
given 'include::include-file.adoc[tag=snippet-a]'
should match /snippet-a content/
should_not match /snippet-b content/
should_not match /non-tagged content/
should_not match /included content/
end
it 'supports multiple tagged selection' do
given 'include::include-file.adoc[tags="snippet-a,snippet-b"]'
should match /snippet-a content/
should match /snippet-b content/
should_not match /non-tagged content/
should_not match /included content/
end
it 'supports tagged selection in language that uses circumfix comments' do
given <<~ADOC
[source, ml]
----
include::include-file.ml[tag=snippet]
----
ADOC
should match /let s = SS.empty;;/
should_not match /(?:tag|end)::snippet\[\]/
end
it 'does not allow execution of system command when allow-uri-read is set' do
options.merge!(attributes: { 'allow-uri-read' => '' })
given <<~ADOC
:app-name: |cat LICENSE # + \\
http://test.com
include::{app-name}[]
ADOC
should match /unresolved/i
should_not match /The MIT License/
end
end
#---------- Helpers ----------
def given(str, opts = {})
input.replace(str)
options.merge!(opts)
end
def using_test_webserver
started = false
server = WEBrick::HTTPServer.new(
BindAddress: '127.0.0.1',
Port: 0,
StartCallback: -> { started = true },
AccessLog: [],
)
server.mount_proc '/hello.json' do |_, res|
res.body = '{"message": "Hello, world!"}'
end
Thread.new { server.start }
Timeout.timeout(1) { :wait until started }
begin
yield server.config[:BindAddress], server.config[:Port]
ensure
server.shutdown
end
end
end
|