| 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("adblockplus", 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("adblockplus", 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("adblockplus", 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 | 
|---|