filewriter_test.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // Copyright 2011 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. goog.provide('goog.testing.fs.FileWriterTest');
  15. goog.setTestOnly('goog.testing.fs.FileWriterTest');
  16. goog.require('goog.Promise');
  17. goog.require('goog.array');
  18. goog.require('goog.events');
  19. goog.require('goog.fs.Error');
  20. goog.require('goog.fs.FileSaver');
  21. goog.require('goog.object');
  22. goog.require('goog.testing.MockClock');
  23. goog.require('goog.testing.events.EventObserver');
  24. goog.require('goog.testing.fs.Blob');
  25. goog.require('goog.testing.fs.FileSystem');
  26. goog.require('goog.testing.jsunit');
  27. var EventType = goog.fs.FileSaver.EventType;
  28. var ReadyState = goog.fs.FileSaver.ReadyState;
  29. /** @type {!goog.testing.fs.File} */
  30. var file;
  31. /** @type {!goog.testing.fs.FileWriter} */
  32. var writer;
  33. /** @type {!goog.testing.MockClock} */
  34. var mockClock;
  35. function setUp() {
  36. // Temporarily install the MockClock to get predictable file modified times.
  37. mockClock = new goog.testing.MockClock(true);
  38. var fs = new goog.testing.fs.FileSystem();
  39. var fileEntry = fs.getRoot().createDirectorySync('foo').createFileSync('bar');
  40. mockClock.uninstall();
  41. file = fileEntry.fileSync();
  42. file.setDataInternal('');
  43. return fileEntry.createWriter().then(function(fileWriter) {
  44. writer = fileWriter;
  45. });
  46. }
  47. function tearDown() {
  48. goog.dispose(writer);
  49. }
  50. function testWrite() {
  51. var observer = createObserver(writer);
  52. mockClock.install();
  53. assertEquals(ReadyState.INIT, writer.getReadyState());
  54. assertPositionAndLength(0, 0, writer);
  55. assertLastModified(0, file);
  56. mockClock.tick(3);
  57. var promise = writeString(writer, 'hello');
  58. assertPositionAndLength(0, 0, writer);
  59. assertEquals(ReadyState.WRITING, writer.getReadyState());
  60. promise =
  61. promise
  62. .then(function() {
  63. assertEquals('hello', file.toString());
  64. assertPositionAndLength(5, 5, writer);
  65. assertLastModified(3, file);
  66. assertEquals(ReadyState.DONE, writer.getReadyState());
  67. assertArrayEquals(
  68. [EventType.WRITE_START, EventType.WRITE, EventType.WRITE_END],
  69. goog.array.map(
  70. observer.getEvents(), function(e) { return e.type; }));
  71. var promise = writeString(writer, ' world');
  72. assertEquals(ReadyState.WRITING, writer.getReadyState());
  73. mockClock.tick();
  74. return promise;
  75. })
  76. .then(function() {
  77. assertEquals('hello world', file.toString());
  78. assertPositionAndLength(11, 11, writer);
  79. assertLastModified(4, file);
  80. assertEquals(ReadyState.DONE, writer.getReadyState());
  81. assertArrayEquals(
  82. [
  83. EventType.WRITE_START, EventType.WRITE, EventType.WRITE_END,
  84. EventType.WRITE_START, EventType.WRITE, EventType.WRITE_END
  85. ],
  86. goog.array.map(
  87. observer.getEvents(), function(e) { return e.type; }));
  88. })
  89. .thenAlways(function() { mockClock.uninstall(); });
  90. mockClock.tick();
  91. return promise;
  92. }
  93. function testSeek() {
  94. mockClock.install();
  95. mockClock.tick(17);
  96. assertLastModified(0, file);
  97. var promise = writeString(writer, 'hello world')
  98. .then(function() {
  99. assertPositionAndLength(11, 11, writer);
  100. assertLastModified(17, file);
  101. writer.seek(6);
  102. assertPositionAndLength(6, 11, writer);
  103. var promise = writeString(writer, 'universe');
  104. mockClock.tick();
  105. return promise;
  106. })
  107. .then(function() {
  108. assertEquals('hello universe', file.toString());
  109. assertPositionAndLength(14, 14, writer);
  110. writer.seek(500);
  111. assertPositionAndLength(14, 14, writer);
  112. var promise = writeString(writer, '!');
  113. mockClock.tick();
  114. return promise;
  115. })
  116. .then(function() {
  117. assertEquals('hello universe!', file.toString());
  118. assertPositionAndLength(15, 15, writer);
  119. writer.seek(-9);
  120. assertPositionAndLength(6, 15, writer);
  121. var promise = writeString(writer, 'foo');
  122. mockClock.tick();
  123. return promise;
  124. })
  125. .then(function() {
  126. assertEquals('hello fooverse!', file.toString());
  127. assertPositionAndLength(9, 15, writer);
  128. writer.seek(-500);
  129. assertPositionAndLength(0, 15, writer);
  130. var promise = writeString(writer, 'bye-o');
  131. mockClock.tick();
  132. return promise;
  133. })
  134. .then(function() {
  135. assertEquals('bye-o fooverse!', file.toString());
  136. assertPositionAndLength(5, 15, writer);
  137. assertLastModified(21, file);
  138. })
  139. .thenAlways(function() { mockClock.uninstall(); });
  140. mockClock.tick();
  141. return promise;
  142. }
  143. function testAbort() {
  144. var observer = createObserver(writer);
  145. mockClock.install();
  146. mockClock.tick(13);
  147. var promise = writeString(writer, 'hello world');
  148. assertEquals(ReadyState.WRITING, writer.getReadyState());
  149. writer.abort();
  150. promise = promise
  151. .then(function() {
  152. assertEquals('', file.toString());
  153. assertEquals(ReadyState.DONE, writer.getReadyState());
  154. assertPositionAndLength(0, 0, writer);
  155. assertLastModified(0, file);
  156. assertArrayEquals(
  157. [EventType.ERROR, EventType.ABORT, EventType.WRITE_END],
  158. goog.array.map(observer.getEvents(), function(e) {
  159. return e.type;
  160. }));
  161. })
  162. .thenAlways(function() { mockClock.uninstall(); });
  163. mockClock.tick();
  164. return promise;
  165. }
  166. function testTruncate() {
  167. // Create the event observer after the initial write is complete.
  168. var observer;
  169. mockClock.install();
  170. var promise =
  171. writeString(writer, 'hello world')
  172. .then(function() {
  173. observer = createObserver(writer);
  174. writer.truncate(5);
  175. assertEquals(ReadyState.WRITING, writer.getReadyState());
  176. assertPositionAndLength(11, 11, writer);
  177. assertLastModified(0, file);
  178. var promise = waitForEvent(writer, EventType.WRITE_END);
  179. mockClock.tick();
  180. return promise;
  181. })
  182. .then(function() {
  183. assertEquals('hello', file.toString());
  184. assertEquals(ReadyState.DONE, writer.getReadyState());
  185. assertPositionAndLength(5, 5, writer);
  186. assertLastModified(7, file);
  187. assertArrayEquals(
  188. [EventType.WRITE_START, EventType.WRITE, EventType.WRITE_END],
  189. goog.array.map(
  190. observer.getEvents(), function(e) { return e.type; }));
  191. writer.truncate(10);
  192. var promise = waitForEvent(writer, EventType.WRITE_END);
  193. mockClock.tick(1);
  194. return promise;
  195. })
  196. .then(function() {
  197. assertEquals('hello\0\0\0\0\0', file.toString());
  198. assertLastModified(8, file);
  199. })
  200. .thenAlways(function() { mockClock.uninstall(); });
  201. mockClock.tick(7);
  202. return promise;
  203. }
  204. function testAbortBeforeWrite() {
  205. var err = assertThrows(function() { writer.abort(); });
  206. assertEquals(goog.fs.Error.ErrorCode.INVALID_STATE, err.code);
  207. }
  208. function testAbortAfterWrite() {
  209. return writeString(writer, 'hello world').then(function() {
  210. var err = assertThrows(function() { writer.abort(); });
  211. assertEquals(goog.fs.Error.ErrorCode.INVALID_STATE, err.code);
  212. });
  213. }
  214. function testWriteDuringWrite() {
  215. writer.write(new goog.testing.fs.Blob('hello'));
  216. var err = assertThrows(function() {
  217. writer.write(new goog.testing.fs.Blob('world'));
  218. });
  219. assertEquals(goog.fs.Error.ErrorCode.INVALID_STATE, err.code);
  220. }
  221. function testSeekDuringWrite() {
  222. writer.write(new goog.testing.fs.Blob('hello world'));
  223. var err = assertThrows(function() { writer.seek(5); });
  224. assertEquals(goog.fs.Error.ErrorCode.INVALID_STATE, err.code);
  225. }
  226. function testTruncateDuringWrite() {
  227. writer.write(new goog.testing.fs.Blob('hello world'));
  228. var err = assertThrows(function() { writer.truncate(5); });
  229. assertEquals(goog.fs.Error.ErrorCode.INVALID_STATE, err.code);
  230. }
  231. function waitForEvent(target, type) {
  232. return new goog.Promise(function(resolve, reject) {
  233. goog.events.listenOnce(target, type, resolve);
  234. });
  235. }
  236. function assertPositionAndLength(expectedPosition, expectedLength, writer) {
  237. assertEquals(expectedPosition, writer.getPosition());
  238. assertEquals(expectedLength, writer.getLength());
  239. }
  240. function assertLastModified(expectedTime, file) {
  241. assertEquals(expectedTime, file.lastModifiedDate.getTime());
  242. }
  243. function writeString(writer, str) {
  244. var promise = waitForEvent(writer, goog.fs.FileSaver.EventType.WRITE_END);
  245. writer.write(new goog.testing.fs.Blob(str));
  246. return promise;
  247. }
  248. function createObserver(writer) {
  249. // Observe all file events fired by the FileWriter.
  250. var observer = new goog.testing.events.EventObserver();
  251. goog.events.listen(writer, goog.object.getValues(EventType), observer);
  252. return observer;
  253. }