| LEFT | RIGHT |
| 1 "use strict"; | 1 "use strict"; |
| 2 | 2 |
| 3 { | 3 { |
| 4 const {IO} = require("io"); | 4 const {IO} = require("io"); |
| 5 const info = require("info"); |
| 6 |
| 5 | 7 |
| 6 const testFileNames = { | 8 const testFileNames = { |
| 7 testData: "testData", | 9 testData: "testData", |
| 8 simpleCheck: "simpleCheck", | 10 simpleCheck: "simpleCheck", |
| 9 write: "writeCheck", | 11 write: "writeCheck", |
| 10 read: "readCheck", | 12 read: "readCheck", |
| 11 rename: "renameCheck" | 13 rename: "renameCheck" |
| 12 }; | 14 }; |
| 13 const testData = { | 15 const testData = { |
| 14 fileName: "file:" + testFileNames.testData, | 16 fileName: "file:" + testFileNames.testData, |
| 15 content: [1, 2, 3], | 17 content: [1, 2, 3], |
| 16 lastModified: Date.now() | 18 lastModified: Date.now() |
| 17 }; | 19 }; |
| 18 | 20 |
| 19 QUnit.module("IO tests", { | 21 const isEdge = info.platform == "edgehtml"; |
| 22 |
| 23 QUnit.module("Edge filter storage", { |
| 20 beforeEach() | 24 beforeEach() |
| 21 { | 25 { |
| 22 return prePopulateStorage(); | 26 if (isEdge) |
| 27 return prePopulateStorage(); |
| 23 }, | 28 }, |
| 24 afterEach() | 29 afterEach() |
| 25 { | 30 { |
| 26 return clearStorage(); | 31 if (isEdge) |
| 32 return clearStorage(); |
| 27 } | 33 } |
| 28 }); | 34 }); |
| 29 | 35 |
| 30 test("statFile", (assert) => | 36 function prePopulateStorage() |
| 37 { |
| 38 return new Promise(resolve => |
| 39 { |
| 40 let db; |
| 41 let req = indexedDB.open("adblockplus", 1); |
| 42 |
| 43 req.onsuccess = event => |
| 44 { |
| 45 db = event.currentTarget.result; |
| 46 let store = db |
| 47 .transaction(["file"], "readwrite") |
| 48 .objectStore("file"); |
| 49 |
| 50 store.put(testData).onsuccess = () => resolve(); |
| 51 }; |
| 52 }); |
| 53 } |
| 54 |
| 55 function clearStorage() |
| 56 { |
| 57 return new Promise(resolve => |
| 58 { |
| 59 let db; |
| 60 let req = indexedDB.open("adblockplus", 1); |
| 61 |
| 62 req.onsuccess = event => |
| 63 { |
| 64 db = event.currentTarget.result; |
| 65 let files = Object.values(testFileNames) |
| 66 .map(fileName => new Promise((resolveFile, reject) => |
| 67 { |
| 68 let store = db |
| 69 .transaction(["file"], "readwrite") |
| 70 .objectStore("file"); |
| 71 |
| 72 store.delete("file:" + fileName).onsuccess = resolveFile; |
| 73 })); |
| 74 |
| 75 Promise.all(files).then(resolve); |
| 76 }; |
| 77 }); |
| 78 } |
| 79 |
| 80 if (isEdge) |
| 81 { |
| 82 test("statFile", assert => testStatFile(assert)); |
| 83 test("readFromFile", assert => testReadFromFile(assert)); |
| 84 test("writeToFile", assert => testWriteToFile(assert)); |
| 85 test("renameFile", assert => testRenameFile(assert)); |
| 86 } |
| 87 else |
| 88 { |
| 89 QUnit.skip("statFile", assert => testStatFile(assert)); |
| 90 QUnit.skip("readFromFile", assert => testReadFromFile(assert)); |
| 91 QUnit.skip("writeToFile", assert => testWriteToFile(assert)); |
| 92 QUnit.skip("renameFile", assert => testRenameFile(assert)); |
| 93 } |
| 94 |
| 95 function testStatFile(assert) |
| 31 { | 96 { |
| 32 const noFileMsg = "returns correct value if file doesn't exist"; | 97 const noFileMsg = "returns correct value if file doesn't exist"; |
| 33 const fileExistsMsg = "returns correct value if file exists"; | 98 const fileExistsMsg = "returns correct value if file exists"; |
| 34 | 99 |
| 35 ok(IO.statFile(testFileNames.simpleCheck) instanceof Promise, | 100 ok(IO.statFile(testFileNames.simpleCheck) instanceof Promise, |
| 36 "returns a promise"); | 101 "returns a promise"); |
| 37 | 102 |
| 38 asyncReadHelper( | 103 asyncReadHelper( |
| 39 IO.statFile, | 104 IO.statFile, |
| 40 testFileNames.testData, | 105 testFileNames.testData, |
| 41 {exists: true, lastModified: testData.lastModified}, | 106 {exists: true, lastModified: testData.lastModified}, |
| 42 fileExistsMsg, | 107 fileExistsMsg, |
| 43 assert); | 108 assert); |
| 44 | 109 |
| 45 asyncReadHelper( | 110 asyncReadHelper( |
| 46 IO.statFile, | 111 IO.statFile, |
| 47 testFileNames.simpleCheck, | 112 testFileNames.simpleCheck, |
| 48 {exists: false}, | 113 {exists: false}, |
| 49 noFileMsg, | 114 noFileMsg, |
| 50 assert); | 115 assert); |
| 51 }); | 116 } |
| 52 | 117 |
| 53 test("writeToFile", (assert) => | 118 function testReadFromFile(assert) |
| 54 { | |
| 55 ok(IO.writeToFile(testFileNames.simpleCheck, ["test"]) instanceof Promise, | |
| 56 "returns a promise"); | |
| 57 | |
| 58 writesCorrectValue(assert); | |
| 59 }); | |
| 60 | |
| 61 function writesCorrectValue(assert) | |
| 62 { | |
| 63 const writeCheck = { | |
| 64 fileName: "file:writeCheck", | |
| 65 content: [1, 2, 3], | |
| 66 lastModified: Date.now() | |
| 67 }; | |
| 68 let done = assert.async(); | |
| 69 | |
| 70 IO.writeToFile(testFileNames.write, writeCheck.content) | |
| 71 .then(() => readFromStorage(writeCheck.fileName)) | |
| 72 .then(result => | |
| 73 { | |
| 74 deepEqual( | |
| 75 Object.keys(writeCheck), | |
| 76 Object.keys(result), | |
| 77 "data is written in the correct format"); | |
| 78 | |
| 79 deepEqual( | |
| 80 writeCheck.content, | |
| 81 result.content, | |
| 82 "data has the correct content"); | |
| 83 done(); | |
| 84 }); | |
| 85 } | |
| 86 | |
| 87 test("readFromFile", (assert) => | |
| 88 { | 119 { |
| 89 const noFileMsg = "returns correct value if file doesn't exist"; | 120 const noFileMsg = "returns correct value if file doesn't exist"; |
| 90 | 121 |
| 91 ok(IO.readFromFile(testFileNames.simpleCheck) instanceof Promise, | 122 ok(IO.readFromFile(testFileNames.simpleCheck) instanceof Promise, |
| 92 "returns a promise"); | 123 "returns a promise"); |
| 93 | 124 |
| 94 asyncReadHelper( | 125 asyncReadHelper( |
| 95 IO.readFromFile, | 126 IO.readFromFile, |
| 96 testFileNames.read, | 127 testFileNames.read, |
| 97 {type: "NoSuchFile"}, | 128 {type: "NoSuchFile"}, |
| 98 noFileMsg, | 129 noFileMsg, |
| 99 assert | 130 assert |
| 100 ); | 131 ); |
| 101 | 132 |
| 102 callsListeners(assert); | 133 callsListeners(assert); |
| 103 }); | 134 } |
| 135 |
| 136 function asyncReadHelper(method, fileName, expectedValue, description, assert) |
| 137 { |
| 138 let done = assert.async(); |
| 139 |
| 140 method(fileName) |
| 141 .then(result => |
| 142 { |
| 143 deepEqual(result, expectedValue, description); |
| 144 done(); |
| 145 }) |
| 146 .catch(error => |
| 147 { |
| 148 deepEqual(error, expectedValue, description); |
| 149 done(); |
| 150 }); |
| 151 } |
| 104 | 152 |
| 105 function callsListeners(assert) | 153 function callsListeners(assert) |
| 106 { | 154 { |
| 107 let done = assert.async(); | 155 let done = assert.async(); |
| 108 let called = []; | 156 let called = []; |
| 109 | 157 |
| 110 IO.readFromFile(testFileNames.testData, (entry) => called.push(entry)) | 158 IO.readFromFile(testFileNames.testData, entry => called.push(entry)) |
| 111 .then(() => | 159 .then(() => |
| 112 { | 160 { |
| 113 deepEqual( | 161 deepEqual( |
| 114 called, | 162 called, |
| 115 testData.content, | 163 testData.content, |
| 116 "calls listeners with the correct values"); | 164 "calls listeners with the correct values"); |
| 117 done(); | 165 done(); |
| 118 }); | 166 }); |
| 119 } | 167 } |
| 120 | 168 |
| 121 test("renameFile", (assert) => | 169 function testWriteToFile(assert) |
| 170 { |
| 171 ok(IO.writeToFile(testFileNames.simpleCheck, ["test"]) instanceof Promise, |
| 172 "returns a promise"); |
| 173 |
| 174 writesCorrectValue(assert); |
| 175 } |
| 176 |
| 177 function writesCorrectValue(assert) |
| 178 { |
| 179 const writeCheck = { |
| 180 fileName: "file:writeCheck", |
| 181 content: [1, 2, 3], |
| 182 lastModified: Date.now() |
| 183 }; |
| 184 let done = assert.async(); |
| 185 |
| 186 IO.writeToFile(testFileNames.write, writeCheck.content) |
| 187 .then(() => readFromStorage(writeCheck.fileName)) |
| 188 .then(result => |
| 189 { |
| 190 deepEqual( |
| 191 Object.keys(writeCheck), |
| 192 Object.keys(result), |
| 193 "data is written in the correct format"); |
| 194 |
| 195 deepEqual( |
| 196 writeCheck.content, |
| 197 result.content, |
| 198 "data has the correct content"); |
| 199 done(); |
| 200 }); |
| 201 } |
| 202 |
| 203 function testRenameFile(assert) |
| 122 { | 204 { |
| 123 ok(IO.renameFile(testFileNames.simpleCheck) instanceof Promise, | 205 ok(IO.renameFile(testFileNames.simpleCheck) instanceof Promise, |
| 124 "returns a promise"); | 206 "returns a promise"); |
| 125 | 207 |
| 126 checkRename(assert); | 208 checkRename(assert); |
| 127 }); | 209 } |
| 128 | 210 |
| 129 function checkRename(assert) | 211 function checkRename(assert) |
| 130 { | 212 { |
| 131 let done = assert.async(); | 213 let done = assert.async(); |
| 132 const expected = { | 214 const expected = { |
| 133 fileName: "file:" + testFileNames.rename, | 215 fileName: "file:" + testFileNames.rename, |
| 134 content: testData.content, | 216 content: testData.content, |
| 135 lastModified: testData.lastModified | 217 lastModified: testData.lastModified |
| 136 }; | 218 }; |
| 137 | 219 |
| 138 IO.renameFile(testFileNames.testData, testFileNames.rename) | 220 IO.renameFile(testFileNames.testData, testFileNames.rename) |
| 139 .then(() => readFromStorage("file:" + testFileNames.rename)) | 221 .then(() => readFromStorage("file:" + testFileNames.rename)) |
| 140 .then(result => | 222 .then(result => |
| 141 { | 223 { |
| 142 deepEqual(result, expected, "overrites file"); | 224 deepEqual(result, expected, "overrites file"); |
| 143 done(); | 225 done(); |
| 144 }); | 226 }); |
| 145 } | 227 } |
| 146 | 228 |
| 147 function asyncReadHelper(method, fileName, expectedValue, description, assert) | |
| 148 { | |
| 149 let done = assert.async(); | |
| 150 method(fileName) | |
| 151 .then(result => | |
| 152 { | |
| 153 deepEqual(result, expectedValue, description); | |
| 154 done(); | |
| 155 }) | |
| 156 .catch(error => | |
| 157 { | |
| 158 deepEqual(error, expectedValue, description); | |
| 159 done(); | |
| 160 }); | |
| 161 } | |
| 162 | |
| 163 function readFromStorage(fileName) | 229 function readFromStorage(fileName) |
| 164 { | 230 { |
| 165 return new Promise(resolve => | 231 return new Promise(resolve => |
| 166 { | 232 { |
| 167 let db; | 233 let db; |
| 168 let req = indexedDB.open("adbp", 1); | 234 let req = indexedDB.open("adblockplus", 1); |
| 169 req.onsuccess = (event) => | 235 req.onsuccess = event => |
| 170 { | 236 { |
| 171 db = event.currentTarget.result; | 237 db = event.currentTarget.result; |
| 172 let store = db | 238 let store = db |
| 173 .transaction(["file"], "readwrite") | 239 .transaction(["file"], "readwrite") |
| 174 .objectStore("file"); | 240 .objectStore("file"); |
| 175 | 241 |
| 176 store.get(fileName).onsuccess = (evt => | 242 store.get(fileName).onsuccess = (evt => |
| 177 resolve(evt.currentTarget.result) | 243 resolve(evt.currentTarget.result) |
| 178 ); | 244 ); |
| 179 }; | 245 }; |
| 180 }); | 246 }); |
| 181 } | 247 } |
| 182 | |
| 183 function prePopulateStorage() | |
| 184 { | |
| 185 return new Promise(resolve => | |
| 186 { | |
| 187 let db; | |
| 188 let req = indexedDB.open("adbp", 1); | |
| 189 | |
| 190 req.onsuccess = (event) => | |
| 191 { | |
| 192 db = event.currentTarget.result; | |
| 193 let store = db | |
| 194 .transaction(["file"], "readwrite") | |
| 195 .objectStore("file"); | |
| 196 | |
| 197 store.put(testData).onsuccess = resolve; | |
| 198 }; | |
| 199 }); | |
| 200 } | |
| 201 | |
| 202 function clearStorage() | |
| 203 { | |
| 204 return new Promise(resolve => | |
| 205 { | |
| 206 let db; | |
| 207 let req = indexedDB.open("adbp", 1); | |
| 208 | |
| 209 req.onsuccess = (event) => | |
| 210 { | |
| 211 db = event.currentTarget.result; | |
| 212 let files = Object.keys(testFileNames) | |
| 213 .map(fileName => new Promise((resolveFile, reject) => | |
| 214 { | |
| 215 let store = db | |
| 216 .transaction(["file"], "readwrite") | |
| 217 .objectStore("file"); | |
| 218 | |
| 219 store.delete("file:" + fileName).onsuccess = resolveFile; | |
| 220 })); | |
| 221 | |
| 222 Promise.all(files).then(resolve); | |
| 223 }; | |
| 224 }); | |
| 225 } | |
| 226 } | 248 } |
| 227 | |
| LEFT | RIGHT |