asciidoctor 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of asciidoctor might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/Gemfile +1 -1
- data/LICENSE +2 -2
- data/README.adoc +461 -0
- data/asciidoctor.gemspec +27 -16
- data/compat/asciidoc.conf +139 -0
- data/lib/asciidoctor.rb +212 -69
- data/lib/asciidoctor/abstract_block.rb +41 -0
- data/lib/asciidoctor/abstract_node.rb +128 -81
- data/lib/asciidoctor/attribute_list.rb +5 -2
- data/lib/asciidoctor/backends/base_template.rb +16 -4
- data/lib/asciidoctor/backends/docbook45.rb +112 -42
- data/lib/asciidoctor/backends/html5.rb +206 -90
- data/lib/asciidoctor/block.rb +5 -5
- data/lib/asciidoctor/cli/invoker.rb +38 -34
- data/lib/asciidoctor/cli/options.rb +3 -3
- data/lib/asciidoctor/document.rb +115 -13
- data/lib/asciidoctor/helpers.rb +16 -0
- data/lib/asciidoctor/lexer.rb +486 -359
- data/lib/asciidoctor/path_resolver.rb +360 -0
- data/lib/asciidoctor/reader.rb +122 -23
- data/lib/asciidoctor/renderer.rb +1 -33
- data/lib/asciidoctor/section.rb +1 -1
- data/lib/asciidoctor/substituters.rb +103 -19
- data/lib/asciidoctor/version.rb +1 -1
- data/man/asciidoctor.1 +6 -6
- data/man/asciidoctor.ad +5 -3
- data/stylesheets/asciidoctor.css +274 -0
- data/test/attributes_test.rb +133 -10
- data/test/blocks_test.rb +302 -17
- data/test/document_test.rb +269 -6
- data/test/fixtures/basic-docinfo.html +1 -0
- data/test/fixtures/basic-docinfo.xml +4 -0
- data/test/fixtures/basic.asciidoc +4 -0
- data/test/fixtures/docinfo.html +1 -0
- data/test/fixtures/docinfo.xml +2 -0
- data/test/fixtures/include-file.asciidoc +22 -1
- data/test/fixtures/stylesheets/custom.css +3 -0
- data/test/invoker_test.rb +38 -6
- data/test/lexer_test.rb +64 -21
- data/test/links_test.rb +4 -0
- data/test/lists_test.rb +251 -12
- data/test/paragraphs_test.rb +225 -30
- data/test/paths_test.rb +174 -0
- data/test/reader_test.rb +89 -2
- data/test/sections_test.rb +518 -16
- data/test/substitutions_test.rb +121 -10
- data/test/tables_test.rb +53 -13
- data/test/test_helper.rb +2 -2
- data/test/text_test.rb +5 -5
- metadata +46 -50
- data/README.asciidoc +0 -296
- data/lib/asciidoctor/errors.rb +0 -5
data/test/paragraphs_test.rb
CHANGED
@@ -1,21 +1,53 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
context
|
3
|
+
context 'Paragraphs' do
|
4
4
|
context 'Normal' do
|
5
|
-
test
|
6
|
-
|
5
|
+
test 'should treat plain text separated by blank lines as paragraphs' do
|
6
|
+
input = <<-EOS
|
7
|
+
Plain text for the win!
|
8
|
+
|
9
|
+
Yep. Text. Plain and simple.
|
10
|
+
EOS
|
11
|
+
output = render_embedded_string input
|
12
|
+
assert_css 'p', output, 2
|
13
|
+
assert_xpath '(//p)[1][text() = "Plain text for the win!"]', output, 1
|
14
|
+
assert_xpath '(//p)[2][text() = "Yep. Text. Plain and simple."]', output, 1
|
7
15
|
end
|
8
16
|
|
9
|
-
test
|
10
|
-
|
17
|
+
test 'should associate block title with paragraph' do
|
18
|
+
input = <<-EOS
|
19
|
+
.Titled
|
20
|
+
Paragraph.
|
21
|
+
|
22
|
+
Winning.
|
23
|
+
EOS
|
24
|
+
output = render_embedded_string input
|
11
25
|
|
12
|
-
|
13
|
-
assert_xpath
|
26
|
+
assert_css 'p', output, 2
|
27
|
+
assert_xpath '(//p)[1]/preceding-sibling::*[@class = "title"]', output, 1
|
28
|
+
assert_xpath '(//p)[1]/preceding-sibling::*[@class = "title"][text() = "Titled"]', output, 1
|
29
|
+
assert_xpath '(//p)[2]/preceding-sibling::*[@class = "title"]', output, 0
|
14
30
|
end
|
15
31
|
|
16
|
-
test
|
17
|
-
|
18
|
-
|
32
|
+
test 'no duplicate block before next section' do
|
33
|
+
input = <<-EOS
|
34
|
+
= Title
|
35
|
+
|
36
|
+
Preamble
|
37
|
+
|
38
|
+
== First Section
|
39
|
+
|
40
|
+
Paragraph 1
|
41
|
+
|
42
|
+
Paragraph 2
|
43
|
+
|
44
|
+
== Second Section
|
45
|
+
|
46
|
+
Last words
|
47
|
+
EOS
|
48
|
+
|
49
|
+
output = render_string input
|
50
|
+
assert_xpath '//p[text() = "Paragraph 2"]', output, 1
|
19
51
|
end
|
20
52
|
|
21
53
|
test 'does not treat wrapped line as a list item' do
|
@@ -40,6 +72,62 @@ paragraph
|
|
40
72
|
assert_xpath %(//p[text()="paragraph\n.wrapped line"]), output, 1
|
41
73
|
end
|
42
74
|
|
75
|
+
test 'interprets normal paragraph style as normal paragraph' do
|
76
|
+
input = <<-EOS
|
77
|
+
[normal]
|
78
|
+
Normal paragraph.
|
79
|
+
Nothing special.
|
80
|
+
EOS
|
81
|
+
|
82
|
+
output = render_embedded_string input
|
83
|
+
assert_css 'p', output, 1
|
84
|
+
end
|
85
|
+
|
86
|
+
test 'normal paragraph terminates at block attribute list' do
|
87
|
+
input = <<-EOS
|
88
|
+
normal text
|
89
|
+
[literal]
|
90
|
+
literal text
|
91
|
+
EOS
|
92
|
+
output = render_embedded_string input
|
93
|
+
assert_css '.paragraph:root', output, 1
|
94
|
+
assert_css '.literalblock:root', output, 1
|
95
|
+
end
|
96
|
+
|
97
|
+
test 'normal paragraph terminates at block delimiter' do
|
98
|
+
input = <<-EOS
|
99
|
+
normal text
|
100
|
+
--
|
101
|
+
text in open block
|
102
|
+
--
|
103
|
+
EOS
|
104
|
+
output = render_embedded_string input
|
105
|
+
assert_css '.paragraph:root', output, 1
|
106
|
+
assert_css '.openblock:root', output, 1
|
107
|
+
end
|
108
|
+
|
109
|
+
test 'normal paragraph terminates at list continuation' do
|
110
|
+
input = <<-EOS
|
111
|
+
normal text
|
112
|
+
+
|
113
|
+
EOS
|
114
|
+
output = render_embedded_string input
|
115
|
+
assert_css '.paragraph:root', output, 2
|
116
|
+
assert_xpath %((/*[@class="paragraph"])[1]/p[text() = "normal text"]), output, 1
|
117
|
+
assert_xpath %((/*[@class="paragraph"])[2]/p[text() = "+"]), output, 1
|
118
|
+
end
|
119
|
+
|
120
|
+
test 'normal style turns literal paragraph into normal paragraph' do
|
121
|
+
input = <<-EOS
|
122
|
+
[normal]
|
123
|
+
normal paragraph,
|
124
|
+
despite the leading indent
|
125
|
+
EOS
|
126
|
+
|
127
|
+
output = render_embedded_string input
|
128
|
+
assert_css '.paragraph:root > p', output, 1
|
129
|
+
end
|
130
|
+
|
43
131
|
test 'expands index term macros in DocBook backend' do
|
44
132
|
input = <<-EOS
|
45
133
|
Here is an index entry for ((tigers)).
|
@@ -81,14 +169,32 @@ Note that multi-entry terms generate separate index entries.
|
|
81
169
|
assert_xpath '(//indexterm)[7]/*', output, 2
|
82
170
|
assert_xpath '(//indexterm)[8]/*', output, 1
|
83
171
|
end
|
172
|
+
|
173
|
+
test 'normal paragraph should honor explicit subs list' do
|
174
|
+
input = <<-EOS
|
175
|
+
[subs="specialcharacters"]
|
176
|
+
*Hey Jude*
|
177
|
+
EOS
|
178
|
+
|
179
|
+
output = render_embedded_string input
|
180
|
+
assert output.include?('*Hey Jude*')
|
181
|
+
end
|
84
182
|
end
|
85
183
|
|
86
|
-
context
|
87
|
-
test
|
88
|
-
|
184
|
+
context 'Literal' do
|
185
|
+
test 'single-line literal paragraphs' do
|
186
|
+
input = <<-EOS
|
187
|
+
LITERALS
|
188
|
+
|
189
|
+
ARE LITERALLY
|
190
|
+
|
191
|
+
AWESOME!
|
192
|
+
EOS
|
193
|
+
output = render_embedded_string input
|
194
|
+
assert_xpath '//pre', output, 3
|
89
195
|
end
|
90
196
|
|
91
|
-
test
|
197
|
+
test 'multi-line literal paragraph' do
|
92
198
|
input = <<-EOS
|
93
199
|
Install instructions:
|
94
200
|
|
@@ -97,29 +203,95 @@ Install instructions:
|
|
97
203
|
|
98
204
|
You're good to go!
|
99
205
|
EOS
|
100
|
-
output =
|
101
|
-
assert_xpath
|
102
|
-
|
206
|
+
output = render_embedded_string input
|
207
|
+
assert_xpath '//pre', output, 1
|
208
|
+
# indentation should be trimmed from literal block
|
209
|
+
assert_xpath %(//pre[text() = "yum install ruby rubygems\ngem install asciidoctor"]), output, 1
|
210
|
+
end
|
211
|
+
|
212
|
+
test 'literal paragraph' do
|
213
|
+
input = <<-EOS
|
214
|
+
[literal]
|
215
|
+
this text is literally literal
|
216
|
+
EOS
|
217
|
+
output = render_embedded_string input
|
218
|
+
assert_xpath %(/*[@class="literalblock"]//pre[text()="this text is literally literal"]), output, 1
|
219
|
+
end
|
220
|
+
|
221
|
+
test 'should read content below literal style verbatim' do
|
222
|
+
input = <<-EOS
|
223
|
+
[literal]
|
224
|
+
image::not-an-image-block[]
|
225
|
+
EOS
|
226
|
+
output = render_embedded_string input
|
227
|
+
assert_xpath %(/*[@class="literalblock"]//pre[text()="image::not-an-image-block[]"]), output, 1
|
228
|
+
assert_css 'img', output, 0
|
229
|
+
end
|
230
|
+
|
231
|
+
test 'listing paragraph' do
|
232
|
+
input = <<-EOS
|
233
|
+
[listing]
|
234
|
+
this text is a listing
|
235
|
+
EOS
|
236
|
+
output = render_embedded_string input
|
237
|
+
assert_xpath %(/*[@class="listingblock"]//pre[text()="this text is a listing"]), output, 1
|
238
|
+
end
|
239
|
+
|
240
|
+
test 'source paragraph' do
|
241
|
+
input = <<-EOS
|
242
|
+
[source]
|
243
|
+
use the source, luke!
|
244
|
+
EOS
|
245
|
+
output = render_embedded_string input
|
246
|
+
assert_xpath %(/*[@class="listingblock"]//pre[@class="highlight"]/code[text()="use the source, luke!"]), output, 1
|
103
247
|
end
|
104
248
|
|
105
|
-
test
|
106
|
-
|
249
|
+
test 'source code paragraph with language' do
|
250
|
+
input = <<-EOS
|
251
|
+
[source, perl]
|
252
|
+
die 'zomg perl sucks';
|
253
|
+
EOS
|
254
|
+
output = render_embedded_string input
|
255
|
+
assert_xpath %(/*[@class="listingblock"]//pre[@class="highlight"]/code[@class="perl"][text()="die 'zomg perl sucks';"]), output, 1
|
107
256
|
end
|
108
257
|
|
109
|
-
test
|
110
|
-
|
258
|
+
test 'literal paragraph terminates at block attribute list' do
|
259
|
+
input = <<-EOS
|
260
|
+
literal text
|
261
|
+
[normal]
|
262
|
+
normal text
|
263
|
+
EOS
|
264
|
+
output = render_embedded_string input
|
265
|
+
assert_xpath %(/*[@class="literalblock"]), output, 1
|
266
|
+
assert_xpath %(/*[@class="paragraph"]), output, 1
|
111
267
|
end
|
112
268
|
|
113
|
-
test
|
114
|
-
|
269
|
+
test 'literal paragraph terminates at block delimiter' do
|
270
|
+
input = <<-EOS
|
271
|
+
literal text
|
272
|
+
--
|
273
|
+
normal text
|
274
|
+
--
|
275
|
+
EOS
|
276
|
+
output = render_embedded_string input
|
277
|
+
assert_xpath %(/*[@class="literalblock"]), output, 1
|
278
|
+
assert_xpath %(/*[@class="openblock"]), output, 1
|
115
279
|
end
|
116
280
|
|
117
|
-
test
|
118
|
-
|
281
|
+
test 'literal paragraph terminates at list continuation' do
|
282
|
+
input = <<-EOS
|
283
|
+
literal text
|
284
|
+
+
|
285
|
+
EOS
|
286
|
+
output = render_embedded_string input
|
287
|
+
assert_xpath %(/*[@class="literalblock"]), output, 1
|
288
|
+
assert_xpath %(/*[@class="literalblock"]//pre[text() = "literal text"]), output, 1
|
289
|
+
assert_xpath %(/*[@class="paragraph"]), output, 1
|
290
|
+
assert_xpath %(/*[@class="paragraph"]/p[text() = "+"]), output, 1
|
119
291
|
end
|
120
292
|
end
|
121
293
|
|
122
|
-
context
|
294
|
+
context 'Quote' do
|
123
295
|
test "quote block" do
|
124
296
|
output = render_string("____\nFamous quote.\n____")
|
125
297
|
assert_xpath '//*[@class = "quoteblock"]', output, 1
|
@@ -137,7 +309,7 @@ You're good to go!
|
|
137
309
|
test "quote block with section body" do
|
138
310
|
output = render_string("____\nFamous quote.\n\nNOTE: That was inspiring.\n____")
|
139
311
|
assert_xpath '//*[@class = "quoteblock"]', output, 1
|
140
|
-
assert_xpath '//*[@class = "quoteblock"]//*[@class = "admonitionblock"]', output, 1
|
312
|
+
assert_xpath '//*[@class = "quoteblock"]//*[@class = "admonitionblock note"]', output, 1
|
141
313
|
end
|
142
314
|
|
143
315
|
test "single-line quote paragraph" do
|
@@ -147,6 +319,18 @@ You're good to go!
|
|
147
319
|
assert_xpath '//*[@class = "quoteblock"]//*[contains(text(), "Famous quote.")]', output, 1
|
148
320
|
end
|
149
321
|
|
322
|
+
test 'quote paragraph terminates at list continuation' do
|
323
|
+
input = <<-EOS
|
324
|
+
[quote]
|
325
|
+
A famouse quote.
|
326
|
+
+
|
327
|
+
EOS
|
328
|
+
output = render_embedded_string input
|
329
|
+
assert_css '.quoteblock:root', output, 1
|
330
|
+
assert_css '.paragraph:root', output, 1
|
331
|
+
assert_xpath %(/*[@class="paragraph"]/p[text() = "+"]), output, 1
|
332
|
+
end
|
333
|
+
|
150
334
|
test "verse paragraph" do
|
151
335
|
output = render_string("[verse]\nFamous verse.")
|
152
336
|
assert_xpath '//*[@class = "verseblock"]', output, 1
|
@@ -179,24 +363,35 @@ You're good to go!
|
|
179
363
|
assert_xpath '//*[@class = "verseblock"]//p', output, 0
|
180
364
|
assert_xpath '//*[@class = "verseblock"]//*[@class = "literalblock"]', output, 0
|
181
365
|
end
|
366
|
+
|
367
|
+
test 'quote paragraph should honor explicit subs list' do
|
368
|
+
input = <<-EOS
|
369
|
+
[subs="specialcharacters"]
|
370
|
+
[quote]
|
371
|
+
*Hey Jude*
|
372
|
+
EOS
|
373
|
+
|
374
|
+
output = render_embedded_string input
|
375
|
+
assert output.include?('*Hey Jude*')
|
376
|
+
end
|
182
377
|
end
|
183
378
|
|
184
379
|
context "special" do
|
185
380
|
test "note multiline syntax" do
|
186
381
|
Asciidoctor::ADMONITION_STYLES.each do |style|
|
187
|
-
assert_xpath "//div[@class='admonitionblock']", render_string("[#{style}]\nThis is a winner.")
|
382
|
+
assert_xpath "//div[@class='admonitionblock #{style.downcase}']", render_string("[#{style}]\nThis is a winner.")
|
188
383
|
end
|
189
384
|
end
|
190
385
|
|
191
386
|
test "note block syntax" do
|
192
387
|
Asciidoctor::ADMONITION_STYLES.each do |style|
|
193
|
-
assert_xpath "//div[@class='admonitionblock']", render_string("[#{style}]\n====\nThis is a winner.\n====")
|
388
|
+
assert_xpath "//div[@class='admonitionblock #{style.downcase}']", render_string("[#{style}]\n====\nThis is a winner.\n====")
|
194
389
|
end
|
195
390
|
end
|
196
391
|
|
197
392
|
test "note inline syntax" do
|
198
393
|
Asciidoctor::ADMONITION_STYLES.each do |style|
|
199
|
-
assert_xpath "//div[@class='admonitionblock']", render_string("#{style}: This is important, fool!")
|
394
|
+
assert_xpath "//div[@class='admonitionblock #{style.downcase}']", render_string("#{style}: This is important, fool!")
|
200
395
|
end
|
201
396
|
end
|
202
397
|
|
data/test/paths_test.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
context 'Path Resolver' do
|
4
|
+
context 'Web Paths' do
|
5
|
+
def setup
|
6
|
+
@resolver = Asciidoctor::PathResolver.new
|
7
|
+
end
|
8
|
+
|
9
|
+
test 'target with absolute path' do
|
10
|
+
assert_equal '/images', @resolver.web_path('/images')
|
11
|
+
assert_equal '/images', @resolver.web_path('/images', '')
|
12
|
+
assert_equal '/images', @resolver.web_path('/images', nil)
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'target with relative path' do
|
16
|
+
assert_equal 'images', @resolver.web_path('images')
|
17
|
+
assert_equal 'images', @resolver.web_path('images', '')
|
18
|
+
assert_equal 'images', @resolver.web_path('images', nil)
|
19
|
+
end
|
20
|
+
|
21
|
+
test 'target with path relative to current directory' do
|
22
|
+
assert_equal './images', @resolver.web_path('./images')
|
23
|
+
assert_equal './images', @resolver.web_path('./images', '')
|
24
|
+
assert_equal './images', @resolver.web_path('./images', nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
test 'target with absolute path ignores start path' do
|
28
|
+
assert_equal '/images', @resolver.web_path('/images', 'foo')
|
29
|
+
assert_equal '/images', @resolver.web_path('/images', '/foo')
|
30
|
+
assert_equal '/images', @resolver.web_path('/images', './foo')
|
31
|
+
end
|
32
|
+
|
33
|
+
test 'target with relative path appended to start path' do
|
34
|
+
assert_equal 'assets/images', @resolver.web_path('images', 'assets')
|
35
|
+
assert_equal '/assets/images', @resolver.web_path('images', '/assets')
|
36
|
+
assert_equal './assets/images', @resolver.web_path('images', './assets')
|
37
|
+
end
|
38
|
+
|
39
|
+
test 'target with path relative to current directory appended to start path' do
|
40
|
+
assert_equal 'assets/images', @resolver.web_path('./images', 'assets')
|
41
|
+
assert_equal '/assets/images', @resolver.web_path('./images', '/assets')
|
42
|
+
assert_equal './assets/images', @resolver.web_path('./images', './assets')
|
43
|
+
end
|
44
|
+
|
45
|
+
test 'normalize target' do
|
46
|
+
assert_equal '../images', @resolver.web_path('../images/../images')
|
47
|
+
end
|
48
|
+
|
49
|
+
test 'append target to start path and normalize' do
|
50
|
+
assert_equal '../images', @resolver.web_path('../images/../images', '../images')
|
51
|
+
assert_equal '../../images', @resolver.web_path('../images', '..')
|
52
|
+
end
|
53
|
+
|
54
|
+
test 'normalize parent directory that follows root' do
|
55
|
+
assert_equal '/tiger.png', @resolver.web_path('/../tiger.png')
|
56
|
+
assert_equal '/tiger.png', @resolver.web_path('/../../tiger.png')
|
57
|
+
end
|
58
|
+
|
59
|
+
test 'uses start when target is empty' do
|
60
|
+
assert_equal 'assets/images', @resolver.web_path('', 'assets/images')
|
61
|
+
assert_equal 'assets/images', @resolver.web_path(nil, 'assets/images')
|
62
|
+
end
|
63
|
+
|
64
|
+
test 'posixfies windows paths' do
|
65
|
+
assert_equal '/images', @resolver.web_path('\\images')
|
66
|
+
assert_equal '../images', @resolver.web_path('..\\images')
|
67
|
+
assert_equal '/images', @resolver.web_path('\\..\\images')
|
68
|
+
assert_equal 'assets/images', @resolver.web_path('assets\\images')
|
69
|
+
assert_equal '../assets/images', @resolver.web_path('assets\\images', '..\\images\\..')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'System Paths' do
|
74
|
+
JAIL = '/home/doctor/docs'
|
75
|
+
|
76
|
+
def setup
|
77
|
+
@resolver = Asciidoctor::PathResolver.new
|
78
|
+
end
|
79
|
+
|
80
|
+
test 'prevents access to paths outside of jail' do
|
81
|
+
assert_equal "#{JAIL}/css", @resolver.system_path('../../../../../css', "#{JAIL}/assets/stylesheets", JAIL)
|
82
|
+
assert_equal "#{JAIL}/css", @resolver.system_path('/../../../../../css', "#{JAIL}/assets/stylesheets", JAIL)
|
83
|
+
assert_equal "#{JAIL}/css", @resolver.system_path('../../../css', '../../..', JAIL)
|
84
|
+
end
|
85
|
+
|
86
|
+
test 'throws exception for illegal path access if recover is false' do
|
87
|
+
begin
|
88
|
+
@resolver.system_path('../../../../../css', "#{JAIL}/assets/stylesheets", JAIL, :recover => false)
|
89
|
+
flunk 'Expecting SecurityError to be raised'
|
90
|
+
rescue SecurityError
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
test 'resolves start path if target is empty' do
|
95
|
+
assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path('', "#{JAIL}/assets/stylesheets", JAIL)
|
96
|
+
assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path(nil, "#{JAIL}/assets/stylesheets", JAIL)
|
97
|
+
end
|
98
|
+
|
99
|
+
test 'resolves start path if target is dot' do
|
100
|
+
assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path('.', "#{JAIL}/assets/stylesheets", JAIL)
|
101
|
+
assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path('./', "#{JAIL}/assets/stylesheets", JAIL)
|
102
|
+
end
|
103
|
+
|
104
|
+
test 'treats absolute target as relative when jail is specified' do
|
105
|
+
assert_equal "#{JAIL}/assets/stylesheets", @resolver.system_path('/', "#{JAIL}/assets/stylesheets", JAIL)
|
106
|
+
assert_equal "#{JAIL}/assets/stylesheets/foo", @resolver.system_path('/foo', "#{JAIL}/assets/stylesheets", JAIL)
|
107
|
+
assert_equal "#{JAIL}/assets/foo", @resolver.system_path('/../foo', "#{JAIL}/assets/stylesheets", JAIL)
|
108
|
+
end
|
109
|
+
|
110
|
+
test 'allows use of absolute target or start if resolved path is sub-path of jail' do
|
111
|
+
assert_equal "#{JAIL}/my/path", @resolver.system_path("#{JAIL}/my/path", '', JAIL)
|
112
|
+
assert_equal "#{JAIL}/my/path", @resolver.system_path("#{JAIL}/my/path", nil, JAIL)
|
113
|
+
assert_equal "#{JAIL}/my/path", @resolver.system_path('', "#{JAIL}/my/path", JAIL)
|
114
|
+
assert_equal "#{JAIL}/my/path", @resolver.system_path(nil, "#{JAIL}/my/path", JAIL)
|
115
|
+
assert_equal "#{JAIL}/my/path", @resolver.system_path('path', "#{JAIL}/my", JAIL)
|
116
|
+
end
|
117
|
+
|
118
|
+
test 'uses jail path if start path is empty' do
|
119
|
+
assert_equal "#{JAIL}/images/tiger.png", @resolver.system_path('images/tiger.png', '', JAIL)
|
120
|
+
assert_equal "#{JAIL}/images/tiger.png", @resolver.system_path('images/tiger.png', nil, JAIL)
|
121
|
+
end
|
122
|
+
|
123
|
+
test 'raises security error if start is not contained within jail' do
|
124
|
+
begin
|
125
|
+
@resolver.system_path('images/tiger.png', '/etc', JAIL)
|
126
|
+
flunk 'Expecting SecurityError to be raised'
|
127
|
+
rescue SecurityError
|
128
|
+
end
|
129
|
+
|
130
|
+
begin
|
131
|
+
@resolver.system_path('.', '/etc', JAIL)
|
132
|
+
flunk 'Expecting SecurityError to be raised'
|
133
|
+
rescue SecurityError
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
test 'resolves absolute directory if jail is not specified' do
|
138
|
+
assert_equal '/usr/share/stylesheet.css', @resolver.system_path('/usr/share/stylesheet.css', '/home/dallen/docs/assets/stylesheets')
|
139
|
+
end
|
140
|
+
|
141
|
+
test 'resolves ancestor directory of start if jail is not specified' do
|
142
|
+
assert_equal '/usr/share/stylesheet.css', @resolver.system_path('../../../../../usr/share/stylesheet.css', '/home/dallen/docs/assets/stylesheets')
|
143
|
+
end
|
144
|
+
|
145
|
+
test 'resolves absolute path if start is absolute and target is relative' do
|
146
|
+
assert_equal '/usr/share/assets/stylesheet.css', @resolver.system_path('assets/stylesheet.css', '/usr/share')
|
147
|
+
end
|
148
|
+
|
149
|
+
test 'resolves relative target relative to current directory if start is empty' do
|
150
|
+
pwd = File.expand_path(Dir.pwd)
|
151
|
+
assert_equal "#{pwd}/images/tiger.png", @resolver.system_path('images/tiger.png', '')
|
152
|
+
assert_equal "#{pwd}/images/tiger.png", @resolver.system_path('images/tiger.png', nil)
|
153
|
+
end
|
154
|
+
|
155
|
+
test 'resolves and normalizes start with target is empty' do
|
156
|
+
pwd = File.expand_path(Dir.pwd)
|
157
|
+
assert_equal '/home/doctor/docs', @resolver.system_path('', '/home/doctor/docs')
|
158
|
+
assert_equal '/home/doctor/docs', @resolver.system_path(nil, '/home/doctor/docs')
|
159
|
+
assert_equal "#{pwd}/assets/images", @resolver.system_path(nil, 'assets/images')
|
160
|
+
assert_equal "#{JAIL}/assets/images", @resolver.system_path('', '../assets/images', JAIL)
|
161
|
+
end
|
162
|
+
|
163
|
+
test 'posixfies windows paths' do
|
164
|
+
assert_equal "#{JAIL}/assets/css", @resolver.system_path('..\\css', 'assets\\stylesheets', JAIL)
|
165
|
+
end
|
166
|
+
|
167
|
+
test 'resolves windows paths when file separator is backlash' do
|
168
|
+
@resolver.file_separator = '\\'
|
169
|
+
assert_equal 'C:\\data\\docs', @resolver.system_path('..', "C:\\data\\docs\\assets", 'C:\\data\\docs')
|
170
|
+
assert_equal 'C:\\data\\docs', @resolver.system_path('..\\..', "C:\\data\\docs\\assets", 'C:\\data\\docs')
|
171
|
+
assert_equal 'C:\\data\\docs\\css', @resolver.system_path('..\\..\\css', "C:\\data\\docs\\assets", 'C:\\data\\docs')
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|