1import unittest 2import os 3from unittest import mock 4 5from mkdocs.structure.files import Files, File, get_files, _sort_files, _filter_paths 6from mkdocs.tests.base import load_config, tempdir, PathAssertionMixin 7 8 9class TestFiles(PathAssertionMixin, unittest.TestCase): 10 11 def test_file_eq(self): 12 file = File('a.md', '/path/to/docs', '/path/to/site', use_directory_urls=False) 13 self.assertTrue(file == File('a.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)) 14 15 def test_file_ne(self): 16 file = File('a.md', '/path/to/docs', '/path/to/site', use_directory_urls=False) 17 # Different filename 18 self.assertTrue(file != File('b.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)) 19 # Different src_path 20 self.assertTrue(file != File('a.md', '/path/to/other', '/path/to/site', use_directory_urls=False)) 21 # Different URL 22 self.assertTrue(file != File('a.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)) 23 24 def test_sort_files(self): 25 self.assertEqual( 26 _sort_files(['b.md', 'bb.md', 'a.md', 'index.md', 'aa.md']), 27 ['index.md', 'a.md', 'aa.md', 'b.md', 'bb.md'] 28 ) 29 30 self.assertEqual( 31 _sort_files(['b.md', 'index.html', 'a.md', 'index.md']), 32 ['index.html', 'index.md', 'a.md', 'b.md'] 33 ) 34 35 self.assertEqual( 36 _sort_files(['a.md', 'index.md', 'b.md', 'index.html']), 37 ['index.md', 'index.html', 'a.md', 'b.md'] 38 ) 39 40 self.assertEqual( 41 _sort_files(['.md', '_.md', 'a.md', 'index.md', '1.md']), 42 ['index.md', '.md', '1.md', '_.md', 'a.md'] 43 ) 44 45 self.assertEqual( 46 _sort_files(['a.md', 'b.md', 'a.md']), 47 ['a.md', 'a.md', 'b.md'] 48 ) 49 50 self.assertEqual( 51 _sort_files(['A.md', 'B.md', 'README.md']), 52 ['README.md', 'A.md', 'B.md'] 53 ) 54 55 def test_md_file(self): 56 f = File('foo.md', '/path/to/docs', '/path/to/site', use_directory_urls=False) 57 self.assertPathsEqual(f.src_path, 'foo.md') 58 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo.md') 59 self.assertPathsEqual(f.dest_path, 'foo.html') 60 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo.html') 61 self.assertEqual(f.url, 'foo.html') 62 self.assertEqual(f.name, 'foo') 63 self.assertTrue(f.is_documentation_page()) 64 self.assertFalse(f.is_static_page()) 65 self.assertFalse(f.is_media_file()) 66 self.assertFalse(f.is_javascript()) 67 self.assertFalse(f.is_css()) 68 69 def test_md_file_use_directory_urls(self): 70 f = File('foo.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) 71 self.assertPathsEqual(f.src_path, 'foo.md') 72 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo.md') 73 self.assertPathsEqual(f.dest_path, 'foo/index.html') 74 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/index.html') 75 self.assertEqual(f.url, 'foo/') 76 self.assertEqual(f.name, 'foo') 77 self.assertTrue(f.is_documentation_page()) 78 self.assertFalse(f.is_static_page()) 79 self.assertFalse(f.is_media_file()) 80 self.assertFalse(f.is_javascript()) 81 self.assertFalse(f.is_css()) 82 83 def test_md_file_nested(self): 84 f = File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=False) 85 self.assertPathsEqual(f.src_path, 'foo/bar.md') 86 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.md') 87 self.assertPathsEqual(f.dest_path, 'foo/bar.html') 88 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.html') 89 self.assertEqual(f.url, 'foo/bar.html') 90 self.assertEqual(f.name, 'bar') 91 self.assertTrue(f.is_documentation_page()) 92 self.assertFalse(f.is_static_page()) 93 self.assertFalse(f.is_media_file()) 94 self.assertFalse(f.is_javascript()) 95 self.assertFalse(f.is_css()) 96 97 def test_md_file_nested_use_directory_urls(self): 98 f = File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) 99 self.assertPathsEqual(f.src_path, 'foo/bar.md') 100 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.md') 101 self.assertPathsEqual(f.dest_path, 'foo/bar/index.html') 102 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar/index.html') 103 self.assertEqual(f.url, 'foo/bar/') 104 self.assertEqual(f.name, 'bar') 105 self.assertTrue(f.is_documentation_page()) 106 self.assertFalse(f.is_static_page()) 107 self.assertFalse(f.is_media_file()) 108 self.assertFalse(f.is_javascript()) 109 self.assertFalse(f.is_css()) 110 111 def test_md_index_file(self): 112 f = File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=False) 113 self.assertPathsEqual(f.src_path, 'index.md') 114 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/index.md') 115 self.assertPathsEqual(f.dest_path, 'index.html') 116 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/index.html') 117 self.assertEqual(f.url, 'index.html') 118 self.assertEqual(f.name, 'index') 119 self.assertTrue(f.is_documentation_page()) 120 self.assertFalse(f.is_static_page()) 121 self.assertFalse(f.is_media_file()) 122 self.assertFalse(f.is_javascript()) 123 self.assertFalse(f.is_css()) 124 125 def test_md_readme_index_file(self): 126 f = File('README.md', '/path/to/docs', '/path/to/site', use_directory_urls=False) 127 self.assertPathsEqual(f.src_path, 'README.md') 128 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/README.md') 129 self.assertPathsEqual(f.dest_path, 'index.html') 130 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/index.html') 131 self.assertEqual(f.url, 'index.html') 132 self.assertEqual(f.name, 'index') 133 self.assertTrue(f.is_documentation_page()) 134 self.assertFalse(f.is_static_page()) 135 self.assertFalse(f.is_media_file()) 136 self.assertFalse(f.is_javascript()) 137 self.assertFalse(f.is_css()) 138 139 def test_md_index_file_use_directory_urls(self): 140 f = File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) 141 self.assertPathsEqual(f.src_path, 'index.md') 142 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/index.md') 143 self.assertPathsEqual(f.dest_path, 'index.html') 144 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/index.html') 145 self.assertEqual(f.url, '.') 146 self.assertEqual(f.name, 'index') 147 self.assertTrue(f.is_documentation_page()) 148 self.assertFalse(f.is_static_page()) 149 self.assertFalse(f.is_media_file()) 150 self.assertFalse(f.is_javascript()) 151 self.assertFalse(f.is_css()) 152 153 def test_md_readme_index_file_use_directory_urls(self): 154 f = File('README.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) 155 self.assertPathsEqual(f.src_path, 'README.md') 156 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/README.md') 157 self.assertPathsEqual(f.dest_path, 'index.html') 158 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/index.html') 159 self.assertEqual(f.url, '.') 160 self.assertEqual(f.name, 'index') 161 self.assertTrue(f.is_documentation_page()) 162 self.assertFalse(f.is_static_page()) 163 self.assertFalse(f.is_media_file()) 164 self.assertFalse(f.is_javascript()) 165 self.assertFalse(f.is_css()) 166 167 def test_md_index_file_nested(self): 168 f = File('foo/index.md', '/path/to/docs', '/path/to/site', use_directory_urls=False) 169 self.assertPathsEqual(f.src_path, 'foo/index.md') 170 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/index.md') 171 self.assertPathsEqual(f.dest_path, 'foo/index.html') 172 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/index.html') 173 self.assertEqual(f.url, 'foo/index.html') 174 self.assertEqual(f.name, 'index') 175 self.assertTrue(f.is_documentation_page()) 176 self.assertFalse(f.is_static_page()) 177 self.assertFalse(f.is_media_file()) 178 self.assertFalse(f.is_javascript()) 179 self.assertFalse(f.is_css()) 180 181 def test_md_index_file_nested_use_directory_urls(self): 182 f = File('foo/index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) 183 self.assertPathsEqual(f.src_path, 'foo/index.md') 184 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/index.md') 185 self.assertPathsEqual(f.dest_path, 'foo/index.html') 186 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/index.html') 187 self.assertEqual(f.url, 'foo/') 188 self.assertEqual(f.name, 'index') 189 self.assertTrue(f.is_documentation_page()) 190 self.assertFalse(f.is_static_page()) 191 self.assertFalse(f.is_media_file()) 192 self.assertFalse(f.is_javascript()) 193 self.assertFalse(f.is_css()) 194 195 def test_static_file(self): 196 f = File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=False) 197 self.assertPathsEqual(f.src_path, 'foo/bar.html') 198 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.html') 199 self.assertPathsEqual(f.dest_path, 'foo/bar.html') 200 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.html') 201 self.assertEqual(f.url, 'foo/bar.html') 202 self.assertEqual(f.name, 'bar') 203 self.assertFalse(f.is_documentation_page()) 204 self.assertTrue(f.is_static_page()) 205 self.assertFalse(f.is_media_file()) 206 self.assertFalse(f.is_javascript()) 207 self.assertFalse(f.is_css()) 208 209 def test_static_file_use_directory_urls(self): 210 f = File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=True) 211 self.assertPathsEqual(f.src_path, 'foo/bar.html') 212 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.html') 213 self.assertPathsEqual(f.dest_path, 'foo/bar.html') 214 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.html') 215 self.assertEqual(f.url, 'foo/bar.html') 216 self.assertEqual(f.name, 'bar') 217 self.assertFalse(f.is_documentation_page()) 218 self.assertTrue(f.is_static_page()) 219 self.assertFalse(f.is_media_file()) 220 self.assertFalse(f.is_javascript()) 221 self.assertFalse(f.is_css()) 222 223 def test_media_file(self): 224 f = File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=False) 225 self.assertPathsEqual(f.src_path, 'foo/bar.jpg') 226 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.jpg') 227 self.assertPathsEqual(f.dest_path, 'foo/bar.jpg') 228 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.jpg') 229 self.assertEqual(f.url, 'foo/bar.jpg') 230 self.assertEqual(f.name, 'bar') 231 self.assertFalse(f.is_documentation_page()) 232 self.assertFalse(f.is_static_page()) 233 self.assertTrue(f.is_media_file()) 234 self.assertFalse(f.is_javascript()) 235 self.assertFalse(f.is_css()) 236 237 def test_media_file_use_directory_urls(self): 238 f = File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True) 239 self.assertPathsEqual(f.src_path, 'foo/bar.jpg') 240 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.jpg') 241 self.assertPathsEqual(f.dest_path, 'foo/bar.jpg') 242 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.jpg') 243 self.assertEqual(f.url, 'foo/bar.jpg') 244 self.assertEqual(f.name, 'bar') 245 self.assertFalse(f.is_documentation_page()) 246 self.assertFalse(f.is_static_page()) 247 self.assertTrue(f.is_media_file()) 248 self.assertFalse(f.is_javascript()) 249 self.assertFalse(f.is_css()) 250 251 def test_javascript_file(self): 252 f = File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=False) 253 self.assertPathsEqual(f.src_path, 'foo/bar.js') 254 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.js') 255 self.assertPathsEqual(f.dest_path, 'foo/bar.js') 256 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.js') 257 self.assertEqual(f.url, 'foo/bar.js') 258 self.assertEqual(f.name, 'bar') 259 self.assertFalse(f.is_documentation_page()) 260 self.assertFalse(f.is_static_page()) 261 self.assertTrue(f.is_media_file()) 262 self.assertTrue(f.is_javascript()) 263 self.assertFalse(f.is_css()) 264 265 def test_javascript_file_use_directory_urls(self): 266 f = File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=True) 267 self.assertPathsEqual(f.src_path, 'foo/bar.js') 268 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.js') 269 self.assertPathsEqual(f.dest_path, 'foo/bar.js') 270 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.js') 271 self.assertEqual(f.url, 'foo/bar.js') 272 self.assertEqual(f.name, 'bar') 273 self.assertFalse(f.is_documentation_page()) 274 self.assertFalse(f.is_static_page()) 275 self.assertTrue(f.is_media_file()) 276 self.assertTrue(f.is_javascript()) 277 self.assertFalse(f.is_css()) 278 279 def test_css_file(self): 280 f = File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=False) 281 self.assertPathsEqual(f.src_path, 'foo/bar.css') 282 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.css') 283 self.assertPathsEqual(f.dest_path, 'foo/bar.css') 284 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.css') 285 self.assertEqual(f.url, 'foo/bar.css') 286 self.assertEqual(f.name, 'bar') 287 self.assertFalse(f.is_documentation_page()) 288 self.assertFalse(f.is_static_page()) 289 self.assertTrue(f.is_media_file()) 290 self.assertFalse(f.is_javascript()) 291 self.assertTrue(f.is_css()) 292 293 def test_css_file_use_directory_urls(self): 294 f = File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=True) 295 self.assertPathsEqual(f.src_path, 'foo/bar.css') 296 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.css') 297 self.assertPathsEqual(f.dest_path, 'foo/bar.css') 298 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.css') 299 self.assertEqual(f.url, 'foo/bar.css') 300 self.assertEqual(f.name, 'bar') 301 self.assertFalse(f.is_documentation_page()) 302 self.assertFalse(f.is_static_page()) 303 self.assertTrue(f.is_media_file()) 304 self.assertFalse(f.is_javascript()) 305 self.assertTrue(f.is_css()) 306 307 def test_file_name_with_space(self): 308 f = File('foo bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=False) 309 self.assertPathsEqual(f.src_path, 'foo bar.md') 310 self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo bar.md') 311 self.assertPathsEqual(f.dest_path, 'foo bar.html') 312 self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo bar.html') 313 self.assertEqual(f.url, 'foo%20bar.html') 314 self.assertEqual(f.name, 'foo bar') 315 316 def test_files(self): 317 fs = [ 318 File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True), 319 File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=True), 320 File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=True), 321 File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True), 322 File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=True), 323 File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=True) 324 ] 325 files = Files(fs) 326 self.assertEqual([f for f in files], fs) 327 self.assertEqual(len(files), 6) 328 self.assertEqual(files.documentation_pages(), [fs[0], fs[1]]) 329 self.assertEqual(files.static_pages(), [fs[2]]) 330 self.assertEqual(files.media_files(), [fs[3], fs[4], fs[5]]) 331 self.assertEqual(files.javascript_files(), [fs[4]]) 332 self.assertEqual(files.css_files(), [fs[5]]) 333 self.assertEqual(files.get_file_from_path('foo/bar.jpg'), fs[3]) 334 self.assertEqual(files.get_file_from_path('foo/bar.jpg'), fs[3]) 335 self.assertEqual(files.get_file_from_path('missing.jpg'), None) 336 self.assertTrue(fs[2].src_path in files) 337 self.assertTrue(fs[2].src_path in files) 338 extra_file = File('extra.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) 339 self.assertFalse(extra_file.src_path in files) 340 files.append(extra_file) 341 self.assertEqual(len(files), 7) 342 self.assertTrue(extra_file.src_path in files) 343 self.assertEqual(files.documentation_pages(), [fs[0], fs[1], extra_file]) 344 345 @tempdir(files=[ 346 'favicon.ico', 347 'index.md' 348 ]) 349 @tempdir(files=[ 350 'base.html', 351 'favicon.ico', 352 'style.css', 353 'foo.md', 354 'README', 355 '.ignore.txt', 356 '.ignore/file.txt', 357 'foo/.ignore.txt', 358 'foo/.ignore/file.txt' 359 ]) 360 def test_add_files_from_theme(self, tdir, ddir): 361 config = load_config(docs_dir=ddir, theme={'name': None, 'custom_dir': tdir}) 362 env = config['theme'].get_env() 363 files = get_files(config) 364 self.assertEqual( 365 [file.src_path for file in files], 366 ['index.md', 'favicon.ico'] 367 ) 368 files.add_files_from_theme(env, config) 369 self.assertEqual( 370 [file.src_path for file in files], 371 ['index.md', 'favicon.ico', 'style.css'] 372 ) 373 # Ensure theme file does not override docs_dir file 374 self.assertEqual( 375 files.get_file_from_path('favicon.ico').abs_src_path, 376 os.path.normpath(os.path.join(ddir, 'favicon.ico')) 377 ) 378 379 def test_filter_paths(self): 380 # Root level file 381 self.assertFalse(_filter_paths('foo.md', 'foo.md', False, ['bar.md'])) 382 self.assertTrue(_filter_paths('foo.md', 'foo.md', False, ['foo.md'])) 383 384 # Nested file 385 self.assertFalse(_filter_paths('foo.md', 'baz/foo.md', False, ['bar.md'])) 386 self.assertTrue(_filter_paths('foo.md', 'baz/foo.md', False, ['foo.md'])) 387 388 # Wildcard 389 self.assertFalse(_filter_paths('foo.md', 'foo.md', False, ['*.txt'])) 390 self.assertTrue(_filter_paths('foo.md', 'foo.md', False, ['*.md'])) 391 392 # Root level dir 393 self.assertFalse(_filter_paths('bar', 'bar', True, ['/baz'])) 394 self.assertFalse(_filter_paths('bar', 'bar', True, ['/baz/'])) 395 self.assertTrue(_filter_paths('bar', 'bar', True, ['/bar'])) 396 self.assertTrue(_filter_paths('bar', 'bar', True, ['/bar/'])) 397 398 # Nested dir 399 self.assertFalse(_filter_paths('bar', 'foo/bar', True, ['/bar'])) 400 self.assertFalse(_filter_paths('bar', 'foo/bar', True, ['/bar/'])) 401 self.assertTrue(_filter_paths('bar', 'foo/bar', True, ['bar/'])) 402 403 # Files that look like dirs (no extension). Note that `is_dir` is `False`. 404 self.assertFalse(_filter_paths('bar', 'bar', False, ['bar/'])) 405 self.assertFalse(_filter_paths('bar', 'foo/bar', False, ['bar/'])) 406 407 def test_get_relative_url_use_directory_urls(self): 408 to_files = [ 409 'index.md', 410 'foo/index.md', 411 'foo/bar/index.md', 412 'foo/bar/baz/index.md', 413 'foo.md', 414 'foo/bar.md', 415 'foo/bar/baz.md' 416 ] 417 418 to_file_urls = [ 419 '.', 420 'foo/', 421 'foo/bar/', 422 'foo/bar/baz/', 423 'foo/', 424 'foo/bar/', 425 'foo/bar/baz/' 426 ] 427 428 from_file = File('img.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True) 429 expected = [ 430 'img.jpg', # img.jpg relative to . 431 '../img.jpg', # img.jpg relative to foo/ 432 '../../img.jpg', # img.jpg relative to foo/bar/ 433 '../../../img.jpg', # img.jpg relative to foo/bar/baz/ 434 '../img.jpg', # img.jpg relative to foo 435 '../../img.jpg', # img.jpg relative to foo/bar 436 '../../../img.jpg' # img.jpg relative to foo/bar/baz 437 ] 438 439 for i, filename in enumerate(to_files): 440 file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=True) 441 self.assertEqual(from_file.url, 'img.jpg') 442 self.assertEqual(file.url, to_file_urls[i]) 443 self.assertEqual(from_file.url_relative_to(file.url), expected[i]) 444 self.assertEqual(from_file.url_relative_to(file), expected[i]) 445 446 from_file = File('foo/img.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True) 447 expected = [ 448 'foo/img.jpg', # foo/img.jpg relative to . 449 'img.jpg', # foo/img.jpg relative to foo/ 450 '../img.jpg', # foo/img.jpg relative to foo/bar/ 451 '../../img.jpg', # foo/img.jpg relative to foo/bar/baz/ 452 'img.jpg', # foo/img.jpg relative to foo 453 '../img.jpg', # foo/img.jpg relative to foo/bar 454 '../../img.jpg' # foo/img.jpg relative to foo/bar/baz 455 ] 456 457 for i, filename in enumerate(to_files): 458 file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=True) 459 self.assertEqual(from_file.url, 'foo/img.jpg') 460 self.assertEqual(file.url, to_file_urls[i]) 461 self.assertEqual(from_file.url_relative_to(file.url), expected[i]) 462 self.assertEqual(from_file.url_relative_to(file), expected[i]) 463 464 from_file = File('index.html', '/path/to/docs', '/path/to/site', use_directory_urls=True) 465 expected = [ 466 '.', # . relative to . 467 '..', # . relative to foo/ 468 '../..', # . relative to foo/bar/ 469 '../../..', # . relative to foo/bar/baz/ 470 '..', # . relative to foo 471 '../..', # . relative to foo/bar 472 '../../..' # . relative to foo/bar/baz 473 ] 474 475 for i, filename in enumerate(to_files): 476 file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=True) 477 self.assertEqual(from_file.url, '.') 478 self.assertEqual(file.url, to_file_urls[i]) 479 self.assertEqual(from_file.url_relative_to(file.url), expected[i]) 480 self.assertEqual(from_file.url_relative_to(file), expected[i]) 481 482 from_file = File('file.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) 483 expected = [ 484 'file/', # file relative to . 485 '../file/', # file relative to foo/ 486 '../../file/', # file relative to foo/bar/ 487 '../../../file/', # file relative to foo/bar/baz/ 488 '../file/', # file relative to foo 489 '../../file/', # file relative to foo/bar 490 '../../../file/' # file relative to foo/bar/baz 491 ] 492 493 for i, filename in enumerate(to_files): 494 file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=True) 495 self.assertEqual(from_file.url, 'file/') 496 self.assertEqual(file.url, to_file_urls[i]) 497 self.assertEqual(from_file.url_relative_to(file.url), expected[i]) 498 self.assertEqual(from_file.url_relative_to(file), expected[i]) 499 500 def test_get_relative_url(self): 501 to_files = [ 502 'index.md', 503 'foo/index.md', 504 'foo/bar/index.md', 505 'foo/bar/baz/index.md', 506 'foo.md', 507 'foo/bar.md', 508 'foo/bar/baz.md' 509 ] 510 511 to_file_urls = [ 512 'index.html', 513 'foo/index.html', 514 'foo/bar/index.html', 515 'foo/bar/baz/index.html', 516 'foo.html', 517 'foo/bar.html', 518 'foo/bar/baz.html' 519 ] 520 521 from_file = File('img.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=False) 522 expected = [ 523 'img.jpg', # img.jpg relative to . 524 '../img.jpg', # img.jpg relative to foo/ 525 '../../img.jpg', # img.jpg relative to foo/bar/ 526 '../../../img.jpg', # img.jpg relative to foo/bar/baz/ 527 'img.jpg', # img.jpg relative to foo.html 528 '../img.jpg', # img.jpg relative to foo/bar.html 529 '../../img.jpg' # img.jpg relative to foo/bar/baz.html 530 ] 531 532 for i, filename in enumerate(to_files): 533 file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=False) 534 self.assertEqual(from_file.url, 'img.jpg') 535 self.assertEqual(file.url, to_file_urls[i]) 536 self.assertEqual(from_file.url_relative_to(file.url), expected[i]) 537 self.assertEqual(from_file.url_relative_to(file), expected[i]) 538 539 from_file = File('foo/img.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=False) 540 expected = [ 541 'foo/img.jpg', # foo/img.jpg relative to . 542 'img.jpg', # foo/img.jpg relative to foo/ 543 '../img.jpg', # foo/img.jpg relative to foo/bar/ 544 '../../img.jpg', # foo/img.jpg relative to foo/bar/baz/ 545 'foo/img.jpg', # foo/img.jpg relative to foo.html 546 'img.jpg', # foo/img.jpg relative to foo/bar.html 547 '../img.jpg' # foo/img.jpg relative to foo/bar/baz.html 548 ] 549 550 for i, filename in enumerate(to_files): 551 file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=False) 552 self.assertEqual(from_file.url, 'foo/img.jpg') 553 self.assertEqual(file.url, to_file_urls[i]) 554 self.assertEqual(from_file.url_relative_to(file.url), expected[i]) 555 self.assertEqual(from_file.url_relative_to(file), expected[i]) 556 557 from_file = File('index.html', '/path/to/docs', '/path/to/site', use_directory_urls=False) 558 expected = [ 559 'index.html', # index.html relative to . 560 '../index.html', # index.html relative to foo/ 561 '../../index.html', # index.html relative to foo/bar/ 562 '../../../index.html', # index.html relative to foo/bar/baz/ 563 'index.html', # index.html relative to foo.html 564 '../index.html', # index.html relative to foo/bar.html 565 '../../index.html' # index.html relative to foo/bar/baz.html 566 ] 567 568 for i, filename in enumerate(to_files): 569 file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=False) 570 self.assertEqual(from_file.url, 'index.html') 571 self.assertEqual(file.url, to_file_urls[i]) 572 self.assertEqual(from_file.url_relative_to(file.url), expected[i]) 573 self.assertEqual(from_file.url_relative_to(file), expected[i]) 574 575 from_file = File('file.html', '/path/to/docs', '/path/to/site', use_directory_urls=False) 576 expected = [ 577 'file.html', # file.html relative to . 578 '../file.html', # file.html relative to foo/ 579 '../../file.html', # file.html relative to foo/bar/ 580 '../../../file.html', # file.html relative to foo/bar/baz/ 581 'file.html', # file.html relative to foo.html 582 '../file.html', # file.html relative to foo/bar.html 583 '../../file.html' # file.html relative to foo/bar/baz.html 584 ] 585 586 for i, filename in enumerate(to_files): 587 file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=False) 588 self.assertEqual(from_file.url, 'file.html') 589 self.assertEqual(file.url, to_file_urls[i]) 590 self.assertEqual(from_file.url_relative_to(file.url), expected[i]) 591 self.assertEqual(from_file.url_relative_to(file), expected[i]) 592 593 @tempdir(files=[ 594 'index.md', 595 'bar.css', 596 'bar.html', 597 'bar.jpg', 598 'bar.js', 599 'bar.md', 600 '.dotfile', 601 'templates/foo.html' 602 ]) 603 def test_get_files(self, tdir): 604 config = load_config(docs_dir=tdir, extra_css=['bar.css'], extra_javascript=['bar.js']) 605 files = get_files(config) 606 expected = ['index.md', 'bar.css', 'bar.html', 'bar.jpg', 'bar.js', 'bar.md'] 607 self.assertIsInstance(files, Files) 608 self.assertEqual(len(files), len(expected)) 609 self.assertEqual([f.src_path for f in files], expected) 610 611 @tempdir(files=[ 612 'README.md', 613 'foo.md' 614 ]) 615 def test_get_files_include_readme_without_index(self, tdir): 616 config = load_config(docs_dir=tdir) 617 files = get_files(config) 618 expected = ['README.md', 'foo.md'] 619 self.assertIsInstance(files, Files) 620 self.assertEqual(len(files), len(expected)) 621 self.assertEqual([f.src_path for f in files], expected) 622 623 @tempdir(files=[ 624 'index.md', 625 'README.md', 626 'foo.md' 627 ]) 628 def test_get_files_exclude_readme_with_index(self, tdir): 629 config = load_config(docs_dir=tdir) 630 files = get_files(config) 631 expected = ['index.md', 'foo.md'] 632 self.assertIsInstance(files, Files) 633 self.assertEqual(len(files), len(expected)) 634 self.assertEqual([f.src_path for f in files], expected) 635 636 @tempdir() 637 @tempdir(files={'test.txt': 'source content'}) 638 def test_copy_file(self, src_dir, dest_dir): 639 file = File('test.txt', src_dir, dest_dir, use_directory_urls=False) 640 dest_path = os.path.join(dest_dir, 'test.txt') 641 self.assertPathNotExists(dest_path) 642 file.copy_file() 643 self.assertPathIsFile(dest_path) 644 645 @tempdir(files={'test.txt': 'destination content'}) 646 @tempdir(files={'test.txt': 'source content'}) 647 def test_copy_file_clean_modified(self, src_dir, dest_dir): 648 file = File('test.txt', src_dir, dest_dir, use_directory_urls=False) 649 file.is_modified = mock.Mock(return_value=True) 650 dest_path = os.path.join(dest_dir, 'test.txt') 651 file.copy_file(dirty=False) 652 self.assertPathIsFile(dest_path) 653 with open(dest_path, 'r', encoding='utf-8') as f: 654 self.assertEqual(f.read(), 'source content') 655 656 @tempdir(files={'test.txt': 'destination content'}) 657 @tempdir(files={'test.txt': 'source content'}) 658 def test_copy_file_dirty_modified(self, src_dir, dest_dir): 659 file = File('test.txt', src_dir, dest_dir, use_directory_urls=False) 660 file.is_modified = mock.Mock(return_value=True) 661 dest_path = os.path.join(dest_dir, 'test.txt') 662 file.copy_file(dirty=True) 663 self.assertPathIsFile(dest_path) 664 with open(dest_path, 'r', encoding='utf-8') as f: 665 self.assertEqual(f.read(), 'source content') 666 667 @tempdir(files={'test.txt': 'destination content'}) 668 @tempdir(files={'test.txt': 'source content'}) 669 def test_copy_file_dirty_not_modified(self, src_dir, dest_dir): 670 file = File('test.txt', src_dir, dest_dir, use_directory_urls=False) 671 file.is_modified = mock.Mock(return_value=False) 672 dest_path = os.path.join(dest_dir, 'test.txt') 673 file.copy_file(dirty=True) 674 self.assertPathIsFile(dest_path) 675 with open(dest_path, 'r', encoding='utf-8') as f: 676 self.assertEqual(f.read(), 'destination content') 677 678 def test_files_append_remove_src_paths(self): 679 fs = [ 680 File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True), 681 File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=True), 682 File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=True), 683 File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True), 684 File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=True), 685 File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=True) 686 ] 687 files = Files(fs) 688 self.assertEqual(len(files), 6) 689 self.assertEqual(len(files.src_paths), 6) 690 extra_file = File('extra.md', '/path/to/docs', '/path/to/site', use_directory_urls=True) 691 self.assertFalse(extra_file.src_path in files) 692 files.append(extra_file) 693 self.assertEqual(len(files), 7) 694 self.assertEqual(len(files.src_paths), 7) 695 self.assertTrue(extra_file.src_path in files) 696 files.remove(extra_file) 697 self.assertEqual(len(files), 6) 698 self.assertEqual(len(files.src_paths), 6) 699 self.assertFalse(extra_file.src_path in files) 700