doc_test.rb 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. require 'test_helper'
  2. require 'docs'
  3. class DocsDocTest < MiniTest::Spec
  4. let :doc do
  5. Class.new Docs::Doc do
  6. self.name = 'name'
  7. self.type = 'type'
  8. end
  9. end
  10. let :page do
  11. { path: 'path', store_path: 'store_path', output: 'output', entries: [entry] }
  12. end
  13. let :entry do
  14. Docs::Entry.new
  15. end
  16. let :store do
  17. Docs::NullStore.new
  18. end
  19. describe ".inherited" do
  20. it "sets .type" do
  21. assert_equal doc.type, Class.new(doc).type
  22. end
  23. end
  24. describe ".name" do
  25. it "returns 'Doc' when the class is Docs::Doc" do
  26. assert_equal 'Doc', Docs::Doc.name
  27. end
  28. end
  29. describe ".name=" do
  30. it "stores .name" do
  31. doc.name = 'test'
  32. assert_equal 'test', doc.name
  33. end
  34. end
  35. describe ".slug" do
  36. it "returns 'doc' when the class is Docs::Doc" do
  37. assert_equal 'doc', Docs::Doc.slug
  38. end
  39. it "returns 'doc~v42' when the class is Docs::Doc and its #version is '42'" do
  40. stub(Docs::Doc).version { '42' }
  41. assert_equal 'doc~v42', Docs::Doc.slug
  42. end
  43. it "returns 'foo~v42' when #slug has been set to 'foo' and #version to '42'" do
  44. doc.slug = 'foo'
  45. doc.version = '42'
  46. assert_equal 'foo~v42', doc.slug
  47. end
  48. end
  49. describe ".slug=" do
  50. it "stores .slug" do
  51. doc.slug = 'test'
  52. assert_equal 'test', doc.slug
  53. end
  54. end
  55. describe ".version=" do
  56. it "stores .version as a string" do
  57. doc.version = 4815162342
  58. assert_equal '4815162342', doc.version
  59. end
  60. end
  61. describe ".release=" do
  62. it "stores .release" do
  63. doc.release = '1'
  64. assert_equal '1', doc.release
  65. end
  66. end
  67. describe ".links=" do
  68. it "stores .links" do
  69. doc.links = { test: true }
  70. assert_equal({ test: true }, doc.links)
  71. end
  72. end
  73. describe ".abstract" do
  74. it "returns nil" do
  75. assert_nil doc.abstract
  76. end
  77. end
  78. describe ".abstract=" do
  79. it "stores .abstract" do
  80. doc.abstract = true
  81. assert doc.abstract
  82. end
  83. end
  84. describe ".path" do
  85. it "returns .slug" do
  86. doc.slug = 'slug'
  87. assert_equal 'slug', doc.path
  88. end
  89. end
  90. describe ".index_path" do
  91. it "returns .path + ::INDEX_FILENAME" do
  92. stub(doc).path { 'path' }
  93. assert_equal File.join('path', Docs::Doc::INDEX_FILENAME), doc.index_path
  94. end
  95. end
  96. describe ".db_path" do
  97. it "returns .path + ::DB_FILENAME" do
  98. stub(doc).path { 'path' }
  99. assert_equal File.join('path', Docs::Doc::DB_FILENAME), doc.db_path
  100. end
  101. end
  102. describe ".new" do
  103. it "raises an error when .abstract is true" do
  104. doc.abstract = true
  105. assert_raises NotImplementedError do
  106. doc.new
  107. end
  108. end
  109. end
  110. describe ".as_json" do
  111. it "returns a hash" do
  112. assert_instance_of Hash, doc.as_json
  113. end
  114. it "includes the doc's name, slug, type, and release" do
  115. assert_equal %i(name slug type), doc.as_json.keys
  116. %w(name slug type release links).each do |attribute|
  117. eval "stub(doc).#{attribute} { attribute }"
  118. assert_equal attribute, doc.as_json[attribute.to_sym]
  119. end
  120. end
  121. end
  122. describe ".store_page" do
  123. it "builds a page" do
  124. any_instance_of(doc) do |instance|
  125. stub(instance).build_page('id') { @called = true; nil }
  126. end
  127. doc.store_page(store, 'id') {}
  128. assert @called
  129. end
  130. context "when the page builds successfully" do
  131. before do
  132. any_instance_of(doc) do |instance|
  133. stub(instance).build_page { page }
  134. end
  135. end
  136. context "and it has :entries" do
  137. it "returns true" do
  138. assert doc.store_page(store, 'id')
  139. end
  140. it "stores a file" do
  141. mock(store).write(page[:store_path], page[:output])
  142. doc.store_page(store, 'id')
  143. end
  144. it "opens the .path directory before storing the file" do
  145. stub(doc).path { 'path' }
  146. stub(store).write { assert false }
  147. mock(store).open('path') do |_, block|
  148. stub(store).write
  149. block.call
  150. end
  151. doc.store_page(store, 'id')
  152. end
  153. end
  154. context "and it doesn't have :entries" do
  155. before do
  156. page[:entries] = []
  157. end
  158. it "returns false" do
  159. refute doc.store_page(store, 'id')
  160. end
  161. it "doesn't store a file" do
  162. dont_allow(store).write
  163. doc.store_page(store, 'id')
  164. end
  165. end
  166. end
  167. context "when the page doesn't build successfully" do
  168. before do
  169. any_instance_of(doc) do |instance|
  170. stub(instance).build_page { nil }
  171. end
  172. end
  173. it "returns false" do
  174. refute doc.store_page(store, 'id')
  175. end
  176. it "doesn't store a file" do
  177. dont_allow(store).write
  178. doc.store_page(store, 'id')
  179. end
  180. end
  181. end
  182. describe ".store_pages" do
  183. it "build the pages" do
  184. any_instance_of(doc) do |instance|
  185. stub(instance).build_pages { @called = true }
  186. end
  187. doc.store_pages(store) {}
  188. assert @called
  189. end
  190. context "when pages are built successfully" do
  191. let :pages do
  192. [
  193. page.deep_dup.tap { |p| page[:entries].first.tap { |e| e.name = 'one' } },
  194. page.deep_dup.tap { |p| page[:entries].first.tap { |e| e.name = 'two' } }
  195. ]
  196. end
  197. before do
  198. any_instance_of(doc) do |instance|
  199. stub(instance).build_pages { |block| pages.each(&block) }
  200. end
  201. end
  202. context "and at least one page has :entries" do
  203. it "returns true" do
  204. assert doc.store_pages(store)
  205. end
  206. it "stores a file for each page that has :entries" do
  207. pages.first.merge!(entries: [], output: '')
  208. mock(store).write(page[:store_path], page[:output])
  209. mock(store).write('index.json', anything)
  210. mock(store).write('db.json', anything)
  211. doc.store_pages(store)
  212. end
  213. it "stores an index that contains all the pages' entries" do
  214. stub(store).write(page[:store_path], page[:output])
  215. stub(store).write('db.json', anything)
  216. mock(store).write('index.json', anything) do |path, json|
  217. json = JSON.parse(json)
  218. assert_equal pages.length, json['entries'].length
  219. assert_includes json['entries'], Docs::Entry.new('one').as_json.stringify_keys
  220. end
  221. doc.store_pages(store)
  222. end
  223. it "stores a db that contains all the pages, indexed by path" do
  224. stub(store).write(page[:store_path], page[:output])
  225. stub(store).write('index.json', anything)
  226. mock(store).write('db.json', anything) do |path, json|
  227. json = JSON.parse(json)
  228. assert_equal page[:output], json[page[:path]]
  229. end
  230. doc.store_pages(store)
  231. end
  232. it "replaces the .path directory before storing the files" do
  233. stub(doc).path { 'path' }
  234. stub(store).write { assert false }
  235. mock(store).replace('path') do |_, block|
  236. stub(store).write
  237. block.call
  238. end
  239. doc.store_pages(store)
  240. end
  241. end
  242. context "and no pages have :entries" do
  243. before do
  244. pages.each { |page| page[:entries] = [] }
  245. end
  246. it "returns false" do
  247. refute doc.store_pages(store)
  248. end
  249. it "doesn't store files" do
  250. dont_allow(store).write
  251. doc.store_pages(store)
  252. end
  253. end
  254. end
  255. context "when no pages are built successfully" do
  256. before do
  257. any_instance_of(doc) do |instance|
  258. stub(instance).build_pages
  259. end
  260. end
  261. it "returns false" do
  262. refute doc.store_pages(store)
  263. end
  264. it "doesn't store files" do
  265. dont_allow(store).write
  266. doc.store_pages(store)
  267. end
  268. end
  269. end
  270. describe ".versions" do
  271. it "returns [self] if no versions have been created" do
  272. assert_equal [doc], doc.versions
  273. end
  274. end
  275. describe ".version" do
  276. context "with no args" do
  277. it "returns @version by default" do
  278. doc.version = 'v'
  279. assert_equal 'v', doc.version
  280. end
  281. end
  282. context "with args" do
  283. it "creates a version subclass" do
  284. version = doc.version('4') { self.release = '8'}
  285. assert_equal [version], doc.versions
  286. assert_nil doc.version
  287. assert_nil doc.release
  288. refute doc.version?
  289. assert version.version?
  290. assert_equal '4', version.version
  291. assert_equal '8', version.release
  292. assert_equal 'name', version.name
  293. assert_equal 'type', version.type
  294. end
  295. end
  296. end
  297. end