ResourceStateManagerTests.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /* eslint-disable
  2. no-return-assign,
  3. no-unused-vars,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. const SandboxedModule = require('sandboxed-module')
  13. const sinon = require('sinon')
  14. const { expect } = require('chai')
  15. const modulePath = require('path').join(
  16. __dirname,
  17. '../../../app/js/ResourceStateManager'
  18. )
  19. const Path = require('path')
  20. const Errors = require('../../../app/js/Errors')
  21. describe('ResourceStateManager', function () {
  22. beforeEach(function () {
  23. this.ResourceStateManager = SandboxedModule.require(modulePath, {
  24. singleOnly: true,
  25. requires: {
  26. fs: (this.fs = {}),
  27. './SafeReader': (this.SafeReader = {}),
  28. },
  29. })
  30. this.basePath = '/path/to/write/files/to'
  31. this.resources = [
  32. { path: 'resource-1-mock' },
  33. { path: 'resource-2-mock' },
  34. { path: 'resource-3-mock' },
  35. ]
  36. this.state = '1234567890'
  37. this.resourceFileName = `${this.basePath}/.project-sync-state`
  38. this.resourceFileContents = `${this.resources[0].path}\n${this.resources[1].path}\n${this.resources[2].path}\nstateHash:${this.state}`
  39. return (this.callback = sinon.stub())
  40. })
  41. describe('saveProjectState', function () {
  42. beforeEach(function () {
  43. return (this.fs.writeFile = sinon.stub().callsArg(2))
  44. })
  45. describe('when the state is specified', function () {
  46. beforeEach(function () {
  47. return this.ResourceStateManager.saveProjectState(
  48. this.state,
  49. this.resources,
  50. this.basePath,
  51. this.callback
  52. )
  53. })
  54. it('should write the resource list to disk', function () {
  55. return this.fs.writeFile
  56. .calledWith(this.resourceFileName, this.resourceFileContents)
  57. .should.equal(true)
  58. })
  59. return it('should call the callback', function () {
  60. return this.callback.called.should.equal(true)
  61. })
  62. })
  63. return describe('when the state is undefined', function () {
  64. beforeEach(function () {
  65. this.state = undefined
  66. this.fs.unlink = sinon.stub().callsArg(1)
  67. return this.ResourceStateManager.saveProjectState(
  68. this.state,
  69. this.resources,
  70. this.basePath,
  71. this.callback
  72. )
  73. })
  74. it('should unlink the resource file', function () {
  75. return this.fs.unlink
  76. .calledWith(this.resourceFileName)
  77. .should.equal(true)
  78. })
  79. it('should not write the resource list to disk', function () {
  80. return this.fs.writeFile.called.should.equal(false)
  81. })
  82. return it('should call the callback', function () {
  83. return this.callback.called.should.equal(true)
  84. })
  85. })
  86. })
  87. describe('checkProjectStateMatches', function () {
  88. describe('when the state matches', function () {
  89. beforeEach(function () {
  90. this.SafeReader.readFile = sinon
  91. .stub()
  92. .callsArgWith(3, null, this.resourceFileContents)
  93. return this.ResourceStateManager.checkProjectStateMatches(
  94. this.state,
  95. this.basePath,
  96. this.callback
  97. )
  98. })
  99. it('should read the resource file', function () {
  100. return this.SafeReader.readFile
  101. .calledWith(this.resourceFileName)
  102. .should.equal(true)
  103. })
  104. return it('should call the callback with the results', function () {
  105. return this.callback
  106. .calledWithMatch(null, this.resources)
  107. .should.equal(true)
  108. })
  109. })
  110. describe('when the state file is not present', function () {
  111. beforeEach(function () {
  112. this.SafeReader.readFile = sinon.stub().callsArg(3)
  113. return this.ResourceStateManager.checkProjectStateMatches(
  114. this.state,
  115. this.basePath,
  116. this.callback
  117. )
  118. })
  119. it('should read the resource file', function () {
  120. return this.SafeReader.readFile
  121. .calledWith(this.resourceFileName)
  122. .should.equal(true)
  123. })
  124. it('should call the callback with an error', function () {
  125. this.callback
  126. .calledWith(sinon.match(Errors.FilesOutOfSyncError))
  127. .should.equal(true)
  128. const message = this.callback.args[0][0].message
  129. expect(message).to.include('invalid state for incremental update')
  130. })
  131. })
  132. return describe('when the state does not match', function () {
  133. beforeEach(function () {
  134. this.SafeReader.readFile = sinon
  135. .stub()
  136. .callsArgWith(3, null, this.resourceFileContents)
  137. return this.ResourceStateManager.checkProjectStateMatches(
  138. 'not-the-original-state',
  139. this.basePath,
  140. this.callback
  141. )
  142. })
  143. it('should call the callback with an error', function () {
  144. this.callback
  145. .calledWith(sinon.match(Errors.FilesOutOfSyncError))
  146. .should.equal(true)
  147. const message = this.callback.args[0][0].message
  148. expect(message).to.include('invalid state for incremental update')
  149. })
  150. })
  151. })
  152. return describe('checkResourceFiles', function () {
  153. describe('when all the files are present', function () {
  154. beforeEach(function () {
  155. this.allFiles = [
  156. this.resources[0].path,
  157. this.resources[1].path,
  158. this.resources[2].path,
  159. ]
  160. return this.ResourceStateManager.checkResourceFiles(
  161. this.resources,
  162. this.allFiles,
  163. this.basePath,
  164. this.callback
  165. )
  166. })
  167. return it('should call the callback', function () {
  168. return this.callback.calledWithExactly().should.equal(true)
  169. })
  170. })
  171. describe('when there is a missing file', function () {
  172. beforeEach(function () {
  173. this.allFiles = [this.resources[0].path, this.resources[1].path]
  174. this.fs.stat = sinon.stub().callsArgWith(1, new Error())
  175. return this.ResourceStateManager.checkResourceFiles(
  176. this.resources,
  177. this.allFiles,
  178. this.basePath,
  179. this.callback
  180. )
  181. })
  182. it('should call the callback with an error', function () {
  183. this.callback
  184. .calledWith(sinon.match(Errors.FilesOutOfSyncError))
  185. .should.equal(true)
  186. const message = this.callback.args[0][0].message
  187. expect(message).to.include(
  188. 'resource files missing in incremental update'
  189. )
  190. })
  191. })
  192. return describe('when a resource contains a relative path', function () {
  193. beforeEach(function () {
  194. this.resources[0].path = '../foo/bar.tex'
  195. this.allFiles = [
  196. this.resources[0].path,
  197. this.resources[1].path,
  198. this.resources[2].path,
  199. ]
  200. return this.ResourceStateManager.checkResourceFiles(
  201. this.resources,
  202. this.allFiles,
  203. this.basePath,
  204. this.callback
  205. )
  206. })
  207. it('should call the callback with an error', function () {
  208. this.callback.calledWith(sinon.match(Error)).should.equal(true)
  209. const message = this.callback.args[0][0].message
  210. expect(message).to.include('relative path in resource file list')
  211. })
  212. })
  213. })
  214. })