PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/test/test_rdoc_servlet.rb

https://gitlab.com/Rockyspade/rdoc
Ruby | 538 lines | 370 code | 167 blank | 1 comment | 2 complexity | a1beef76627b1462ec20bb1d040de784 MD5 | raw file
  1. # frozen_string_literal: false
  2. require 'rdoc/test_case'
  3. class TestRDocServlet < RDoc::TestCase
  4. def setup
  5. super
  6. @orig_gem_path = Gem.path
  7. @tempdir = File.join Dir.tmpdir, "test_rdoc_servlet_#{$$}"
  8. Gem.use_paths @tempdir
  9. Gem.ensure_gem_subdirectories @tempdir
  10. @spec = Gem::Specification.new 'spec', '1.0'
  11. @spec.loaded_from = @spec.spec_file
  12. Gem::Specification.reset
  13. Gem::Specification.all = [@spec]
  14. @server = {}
  15. def @server.mount(*) end
  16. @stores = {}
  17. @cache = Hash.new { |hash, store| hash[store] = {} }
  18. @extra_dirs = [File.join(@tempdir, 'extra1'), File.join(@tempdir, 'extra2')]
  19. @s = RDoc::Servlet.new @server, @stores, @cache, nil, @extra_dirs
  20. @req = WEBrick::HTTPRequest.new :Logger => nil
  21. @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
  22. def @req.path= path
  23. instance_variable_set :@path, path
  24. end
  25. @req.instance_variable_set :@header, Hash.new { |h, k| h[k] = [] }
  26. @base = File.join @tempdir, 'base'
  27. @system_dir = File.join @tempdir, 'base', 'system'
  28. @home_dir = File.join @tempdir, 'home'
  29. @gem_doc_dir = File.join @tempdir, 'doc'
  30. @orig_base = RDoc::RI::Paths::BASE
  31. RDoc::RI::Paths::BASE.replace @base
  32. @orig_ri_path_homedir = RDoc::RI::Paths::HOMEDIR
  33. RDoc::RI::Paths::HOMEDIR.replace @home_dir
  34. RDoc::RI::Paths.instance_variable_set \
  35. :@gemdirs, %w[/nonexistent/gems/example-1.0/ri]
  36. end
  37. def teardown
  38. super
  39. Gem.use_paths(*@orig_gem_path)
  40. Gem::Specification.reset
  41. FileUtils.rm_rf @tempdir
  42. RDoc::RI::Paths::BASE.replace @orig_base
  43. RDoc::RI::Paths::HOMEDIR.replace @orig_ri_path_homedir
  44. RDoc::RI::Paths.instance_variable_set :@gemdirs, nil
  45. end
  46. def test_asset
  47. temp_dir do
  48. FileUtils.mkdir 'css'
  49. now = Time.now
  50. open 'css/rdoc.css', 'w' do |io| io.write 'h1 { color: red }' end
  51. File.utime now, now, 'css/rdoc.css'
  52. @s.asset_dirs[:darkfish] = '.'
  53. @req.path = '/css/rdoc.css'
  54. @s.asset :darkfish, @req, @res
  55. assert_equal 'h1 { color: red }', @res.body
  56. assert_equal 'text/css', @res.content_type
  57. assert_equal now.httpdate, @res['last-modified']
  58. end
  59. end
  60. def test_do_GET
  61. touch_system_cache_path
  62. @req.path = '/ruby/Missing.html'
  63. @s.do_GET @req, @res
  64. assert_equal 404, @res.status
  65. end
  66. def test_do_GET_asset_darkfish
  67. temp_dir do
  68. FileUtils.mkdir 'css'
  69. FileUtils.touch 'css/rdoc.css'
  70. @s.asset_dirs[:darkfish] = '.'
  71. @req.path = '/css/rdoc.css'
  72. @s.do_GET @req, @res
  73. assert_equal 'text/css', @res.content_type
  74. end
  75. end
  76. def test_do_GET_asset_json_index
  77. temp_dir do
  78. FileUtils.mkdir 'js'
  79. FileUtils.touch 'js/navigation.js'
  80. @s.asset_dirs[:json_index] = '.'
  81. @req.path = '/js/navigation.js'
  82. @s.do_GET @req, @res
  83. assert_equal 'application/javascript', @res.content_type
  84. end
  85. end
  86. def test_do_GET_error
  87. touch_system_cache_path
  88. def @req.path() raise 'no' end
  89. @s.do_GET @req, @res
  90. assert_equal 500, @res.status
  91. end
  92. def test_do_GET_mount_path
  93. @s = RDoc::Servlet.new @server, @stores, @cache, '/mount/path'
  94. temp_dir do
  95. FileUtils.mkdir 'css'
  96. FileUtils.touch 'css/rdoc.css'
  97. @s.asset_dirs[:darkfish] = '.'
  98. @req.path = '/mount/path/css/rdoc.css'
  99. @s.do_GET @req, @res
  100. assert_equal 'text/css', @res.content_type
  101. end
  102. end
  103. def do_GET_not_found
  104. touch_system_cache_path
  105. @req.path = "/#{@spec.full_name}"
  106. @s.do_GET @req, @res
  107. assert_equal 404, @res.status
  108. end
  109. def test_do_GET_not_modified
  110. touch_system_cache_path
  111. @req.header['if-modified-since'] = [(Time.now + 10).httpdate]
  112. @req.path = '/ruby/Missing.html'
  113. assert_raises WEBrick::HTTPStatus::NotModified do
  114. @s.do_GET @req, @res
  115. end
  116. end
  117. def test_do_GET_root
  118. touch_system_cache_path
  119. @req.path = '/'
  120. @s.do_GET @req, @res
  121. assert_equal 'text/html', @res.content_type
  122. assert_match %r%<title>Local RDoc Documentation</title>%, @res.body
  123. end
  124. def test_do_GET_root_search
  125. touch_system_cache_path
  126. @req.path = '/js/search_index.js'
  127. @s.do_GET @req, @res
  128. assert_equal 'application/javascript', @res.content_type, @res.body
  129. end
  130. def test_documentation_page_class
  131. store = RDoc::Store.new
  132. generator = @s.generator_for store
  133. file = store.add_file 'file.rb'
  134. klass = file.add_class RDoc::NormalClass, 'Klass'
  135. klass.add_class RDoc::NormalClass, 'Sub'
  136. @s.documentation_page store, generator, 'Klass::Sub.html', @req, @res
  137. assert_match %r%<title>class Klass::Sub - </title>%, @res.body
  138. assert_match %r%<body id="top" role="document" class="class">%, @res.body
  139. end
  140. def test_documentation_page_not_found
  141. store = RDoc::Store.new
  142. generator = @s.generator_for store
  143. @req.path = '/ruby/Missing.html'
  144. @s.documentation_page store, generator, 'Missing.html', @req, @res
  145. assert_equal 404, @res.status
  146. end
  147. def test_documentation_page_page
  148. store = RDoc::Store.new
  149. generator = @s.generator_for store
  150. readme = store.add_file 'README.rdoc'
  151. readme.parser = RDoc::Parser::Simple
  152. @s.documentation_page store, generator, 'README_rdoc.html', @req, @res
  153. assert_match %r%<title>README - </title>%, @res.body
  154. assert_match %r%<body [^>]+ class="file">%, @res.body
  155. end
  156. def test_documentation_source
  157. store, path = @s.documentation_source '/ruby/Object.html'
  158. assert_equal @system_dir, store.path
  159. assert_equal 'Object.html', path
  160. end
  161. def test_documentation_source_cached
  162. cached_store = RDoc::Store.new
  163. @stores['ruby'] = cached_store
  164. store, path = @s.documentation_source '/ruby/Object.html'
  165. assert_same cached_store, store
  166. assert_equal 'Object.html', path
  167. end
  168. def test_error
  169. e = RuntimeError.new 'foo'
  170. e.set_backtrace caller
  171. @s.error e, @req, @res
  172. assert_equal 'text/html', @res.content_type
  173. assert_equal 500, @res.status
  174. assert_match %r%<title>Error%, @res.body
  175. end
  176. def test_generator_for
  177. store = RDoc::Store.new
  178. store.main = 'MAIN_PAGE.rdoc'
  179. store.title = 'Title'
  180. generator = @s.generator_for store
  181. refute generator.file_output
  182. assert_equal '..', generator.asset_rel_path
  183. assert_equal 'MAIN_PAGE.rdoc', @s.options.main_page
  184. assert_equal 'Title', @s.options.title
  185. assert_kind_of RDoc::RDoc, store.rdoc
  186. assert_same generator, store.rdoc.generator
  187. end
  188. def test_if_modified_since
  189. skip 'File.utime on directory not supported' if Gem.win_platform?
  190. temp_dir do
  191. now = Time.now
  192. File.utime now, now, '.'
  193. @s.if_modified_since @req, @res, '.'
  194. assert_equal now.to_i, Time.parse(@res['last-modified']).to_i
  195. end
  196. end
  197. def test_if_modified_since_not_modified
  198. skip 'File.utime on directory not supported' if Gem.win_platform?
  199. temp_dir do
  200. now = Time.now
  201. File.utime now, now, '.'
  202. @req.header['if-modified-since'] = [(now + 10).httpdate]
  203. assert_raises WEBrick::HTTPStatus::NotModified do
  204. @s.if_modified_since @req, @res, '.'
  205. end
  206. assert_equal now.to_i, Time.parse(@res['last-modified']).to_i
  207. end
  208. end
  209. def test_installed_docs
  210. touch_system_cache_path
  211. touch_extra_cache_path
  212. expected = [
  213. ['My Extra Documentation', 'extra-1/', true, :extra,
  214. @extra_dirs[0]],
  215. ['Extra Documentation', 'extra-2/', false, :extra,
  216. @extra_dirs[1]],
  217. ['Ruby Documentation', 'ruby/', true, :system,
  218. @system_dir],
  219. ['Site Documentation', 'site/', false, :site,
  220. File.join(@base, 'site')],
  221. ['Home Documentation', 'home/', false, :home,
  222. RDoc::RI::Paths::HOMEDIR],
  223. ['spec-1.0', 'spec-1.0/', false, :gem,
  224. File.join(@spec.doc_dir, 'ri')],
  225. ]
  226. assert_equal expected, @s.installed_docs
  227. end
  228. def test_not_found
  229. generator = @s.generator_for RDoc::Store.new
  230. @req.path = '/ruby/Missing.html'
  231. @s.not_found generator, @req, @res
  232. assert_equal 404, @res.status
  233. assert_match %r%<title>Not Found</title>%, @res.body
  234. assert_match %r%<kbd>/ruby/Missing\.html</kbd>%, @res.body
  235. end
  236. def test_not_found_message
  237. generator = @s.generator_for RDoc::Store.new
  238. @req.path = '/ruby/Missing.html'
  239. @s.not_found generator, @req, @res, 'woo, this is a message'
  240. assert_equal 404, @res.status
  241. assert_match %r%<title>Not Found</title>%, @res.body
  242. assert_match %r%woo, this is a message%, @res.body
  243. end
  244. def test_ri_paths
  245. paths = @s.ri_paths
  246. expected = [
  247. [@extra_dirs[0], :extra],
  248. [@extra_dirs[1], :extra],
  249. [@system_dir, :system],
  250. [File.join(@base, 'site'), :site],
  251. [RDoc::RI::Paths::HOMEDIR, :home],
  252. [File.join(@spec.doc_dir, 'ri'), :gem],
  253. ]
  254. assert_equal expected, paths.to_a
  255. end
  256. def test_root
  257. @s.root @req, @res
  258. assert_equal 'text/html', @res.content_type
  259. assert_match %r%<title>Local RDoc Documentation</title>%, @res.body
  260. end
  261. def test_root_search
  262. touch_system_cache_path
  263. touch_extra_cache_path
  264. @s.root_search @req, @res
  265. assert_equal 'application/javascript', @res.content_type
  266. @res.body =~ /\{.*\}/
  267. index = JSON.parse $&
  268. expected = {
  269. 'index' => {
  270. 'searchIndex' => %w[
  271. My\ Extra\ Documentation
  272. Ruby\ Documentation
  273. ],
  274. 'longSearchIndex' => %w[
  275. My\ Extra\ Documentation
  276. Ruby\ Documentation
  277. ],
  278. 'info' => [
  279. ['My Extra Documentation', '', @extra_dirs[0], '',
  280. 'My Extra Documentation'],
  281. ['Ruby Documentation', '', 'ruby', '',
  282. 'Documentation for the Ruby standard library'],
  283. ],
  284. }
  285. }
  286. assert_equal expected, index
  287. end
  288. def test_show_documentation_index
  289. touch_system_cache_path
  290. @req.path = '/ruby'
  291. @s.show_documentation @req, @res
  292. assert_equal 'text/html', @res.content_type
  293. assert_match %r%<title>Standard Library Documentation%, @res.body
  294. end
  295. def test_show_documentation_table_of_contents
  296. touch_system_cache_path
  297. @req.path = '/ruby/table_of_contents.html'
  298. @s.show_documentation @req, @res
  299. assert_equal 'text/html', @res.content_type
  300. assert_match %r%<title>Table of Contents - Standard Library Documentation%,
  301. @res.body
  302. end
  303. def test_show_documentation_page
  304. touch_system_cache_path
  305. @req.path = '/ruby/Missing.html'
  306. @s.show_documentation @req, @res
  307. assert_equal 404, @res.status
  308. end
  309. def test_show_documentation_search_index
  310. touch_system_cache_path
  311. @req.path = '/ruby/js/search_index.js'
  312. @s.show_documentation @req, @res
  313. assert_equal 'application/javascript', @res.content_type
  314. assert_match %r%\Avar search_data =%, @res.body
  315. end
  316. def test_store_for_gem
  317. ri_dir = File.join @gem_doc_dir, 'spec-1.0', 'ri'
  318. FileUtils.mkdir_p ri_dir
  319. FileUtils.touch File.join ri_dir, 'cache.ri'
  320. store = @s.store_for 'spec-1.0'
  321. assert_equal File.join(@gem_doc_dir, 'spec-1.0', 'ri'), store.path
  322. assert_equal :gem, store.type
  323. end
  324. def test_store_for_home
  325. store = @s.store_for 'home'
  326. assert_equal @home_dir, store.path
  327. assert_equal :home, store.type
  328. end
  329. def test_store_for_missing_documentation
  330. FileUtils.mkdir_p(File.join @gem_doc_dir, 'spec-1.0', 'ri')
  331. e = assert_raises WEBrick::HTTPStatus::NotFound do
  332. @s.store_for 'spec-1.0'
  333. end
  334. assert_equal 'Could not find documentation for "spec-1.0". Please run `gem rdoc --ri gem_name`',
  335. e.message
  336. end
  337. def test_store_for_missing_gem
  338. e = assert_raises WEBrick::HTTPStatus::NotFound do
  339. @s.store_for 'missing'
  340. end
  341. assert_equal 'Could not find gem "missing". Are you sure you installed it?',
  342. e.message
  343. end
  344. def test_store_for_ruby
  345. store = @s.store_for 'ruby'
  346. assert_equal @system_dir, store.path
  347. assert_equal :system, store.type
  348. end
  349. def test_store_for_site
  350. store = @s.store_for 'site'
  351. assert_equal File.join(@base, 'site'), store.path
  352. assert_equal :site, store.type
  353. end
  354. def test_store_for_extra
  355. store = @s.store_for 'extra-1'
  356. assert_equal @extra_dirs.first, store.path
  357. assert_equal :extra, store.type
  358. end
  359. def touch_system_cache_path
  360. store = RDoc::Store.new @system_dir
  361. store.title = 'Standard Library Documentation'
  362. FileUtils.mkdir_p File.dirname store.cache_path
  363. store.save
  364. end
  365. def touch_extra_cache_path
  366. store = RDoc::Store.new @extra_dirs.first
  367. store.title = 'My Extra Documentation'
  368. FileUtils.mkdir_p File.dirname store.cache_path
  369. store.save
  370. end
  371. end