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