|
| 1 | +if (typeof exports === 'object') { |
| 2 | + var assert = require('assert'); |
| 3 | + var alasql = require('..'); |
| 4 | + var fs = require('fs'); |
| 5 | +} else { |
| 6 | + __dirname = '.'; |
| 7 | +} |
| 8 | + |
| 9 | +describe('Test 107-B - Update existing Excel spreadsheet with sourcefilename and range', function () { |
| 10 | + if (typeof exports === 'object') { |
| 11 | + it('1. Create initial XLSX file with data', function (done) { |
| 12 | + var data = [ |
| 13 | + {a: 1, b: 2, c: 3}, |
| 14 | + {a: 4, b: 5, c: 6}, |
| 15 | + {a: 7, b: 8, c: 9}, |
| 16 | + ]; |
| 17 | + alasql('SELECT * INTO XLSX("' + __dirname + '/test107-B-base.xlsx", {headers:true}) FROM ?', [ |
| 18 | + data, |
| 19 | + ]); |
| 20 | + // Verify file was created and read back content |
| 21 | + assert(fs.existsSync(__dirname + '/test107-B-base.xlsx')); |
| 22 | + alasql( |
| 23 | + 'SELECT * FROM XLSX("' + __dirname + '/test107-B-base.xlsx", {headers:true})', |
| 24 | + [], |
| 25 | + function (res) { |
| 26 | + assert.deepEqual(res, data); |
| 27 | + done(); |
| 28 | + } |
| 29 | + ); |
| 30 | + }); |
| 31 | + |
| 32 | + it('2. Update existing file at specific range with sourcefilename', function (done) { |
| 33 | + var updateData = [ |
| 34 | + {x: 100, y: 200, z: 300}, |
| 35 | + {x: 400, y: 500, z: 600}, |
| 36 | + ]; |
| 37 | + |
| 38 | + alasql( |
| 39 | + 'SELECT * INTO XLSX("' + |
| 40 | + __dirname + |
| 41 | + '/test107-B-updated.xlsx", {sourcefilename:"' + |
| 42 | + __dirname + |
| 43 | + '/test107-B-base.xlsx", sheetid:"Sheet 1", range:"E5", headers:true}) FROM ?', |
| 44 | + [updateData], |
| 45 | + function (res) { |
| 46 | + assert(res == 1); |
| 47 | + // Verify updated file was created |
| 48 | + assert(fs.existsSync(__dirname + '/test107-B-updated.xlsx')); |
| 49 | + // Read back and verify content - check that original data is preserved at A1:C3 |
| 50 | + alasql( |
| 51 | + 'SELECT * FROM XLSX("' + |
| 52 | + __dirname + |
| 53 | + '/test107-B-updated.xlsx", {headers:true, sheetid:"Sheet 1", range:"A1:C4"})', |
| 54 | + [], |
| 55 | + function (original) { |
| 56 | + // Original data should still be there |
| 57 | + var expectedOriginal = [ |
| 58 | + {a: 1, b: 2, c: 3}, |
| 59 | + {a: 4, b: 5, c: 6}, |
| 60 | + {a: 7, b: 8, c: 9}, |
| 61 | + ]; |
| 62 | + assert.deepEqual(original, expectedOriginal); |
| 63 | + // Read the new data at E5:G6 |
| 64 | + alasql( |
| 65 | + 'SELECT * FROM XLSX("' + |
| 66 | + __dirname + |
| 67 | + '/test107-B-updated.xlsx", {headers:true, sheetid:"Sheet 1", range:"E5:G7"})', |
| 68 | + [], |
| 69 | + function (updated) { |
| 70 | + var expectedUpdated = [ |
| 71 | + {x: 100, y: 200, z: 300}, |
| 72 | + {x: 400, y: 500, z: 600}, |
| 73 | + ]; |
| 74 | + assert.deepEqual(updated, expectedUpdated); |
| 75 | + done(); |
| 76 | + } |
| 77 | + ); |
| 78 | + } |
| 79 | + ); |
| 80 | + } |
| 81 | + ); |
| 82 | + }); |
| 83 | + |
| 84 | + it('3. Update existing file without headers at range B3', function (done) { |
| 85 | + var updateData = [ |
| 86 | + {hour: 10, minute: 30, second: 45}, |
| 87 | + {hour: 11, minute: 45, second: 20}, |
| 88 | + ]; |
| 89 | + |
| 90 | + alasql( |
| 91 | + 'SELECT * INTO XLSX("' + |
| 92 | + __dirname + |
| 93 | + '/test107-B-no-headers.xlsx", {sourcefilename:"' + |
| 94 | + __dirname + |
| 95 | + '/test107-B-base.xlsx", sheetid:"Sheet 1", range:"B3", headers:false}) FROM ?', |
| 96 | + [updateData], |
| 97 | + function (res) { |
| 98 | + assert(res == 1); |
| 99 | + assert(fs.existsSync(__dirname + '/test107-B-no-headers.xlsx')); |
| 100 | + // Read back the data at B3:D4 (no headers, so will be read as columns B, C, D) |
| 101 | + alasql( |
| 102 | + 'SELECT * FROM XLSX("' + |
| 103 | + __dirname + |
| 104 | + '/test107-B-no-headers.xlsx", {headers:false, sheetid:"Sheet 1", range:"B3:D4"})', |
| 105 | + [], |
| 106 | + function (result) { |
| 107 | + var expectedResult = [ |
| 108 | + {B: 10, C: 30, D: 45}, |
| 109 | + {B: 11, C: 45, D: 20}, |
| 110 | + ]; |
| 111 | + assert.deepEqual(result, expectedResult); |
| 112 | + done(); |
| 113 | + } |
| 114 | + ); |
| 115 | + } |
| 116 | + ); |
| 117 | + }); |
| 118 | + |
| 119 | + it('4. Overwrite same file with sourcefilename pointing to itself', function (done) { |
| 120 | + // First create a file |
| 121 | + var initialData = [{name: 'John', age: 25}]; |
| 122 | + alasql('SELECT * INTO XLSX("' + __dirname + '/test107-B-self.xlsx", {headers:true}) FROM ?', [ |
| 123 | + initialData, |
| 124 | + ]); |
| 125 | + |
| 126 | + // Then update it in place |
| 127 | + var newData = [{value: 999, status: 'updated'}]; |
| 128 | + alasql( |
| 129 | + 'SELECT * INTO XLSX("' + |
| 130 | + __dirname + |
| 131 | + '/test107-B-self.xlsx", {sourcefilename:"' + |
| 132 | + __dirname + |
| 133 | + '/test107-B-self.xlsx", sheetid:"Sheet 1", range:"D10", headers:true}) FROM ?', |
| 134 | + [newData], |
| 135 | + function (res) { |
| 136 | + assert(res == 1); |
| 137 | + assert(fs.existsSync(__dirname + '/test107-B-self.xlsx')); |
| 138 | + // Read back and verify both original and new data exist |
| 139 | + alasql( |
| 140 | + 'SELECT * FROM XLSX("' + |
| 141 | + __dirname + |
| 142 | + '/test107-B-self.xlsx", {headers:true, sheetid:"Sheet 1", range:"A1:B2"})', |
| 143 | + [], |
| 144 | + function (original) { |
| 145 | + // Original data should be at A1:B1 |
| 146 | + var expectedOriginal = [{name: 'John', age: 25}]; |
| 147 | + assert.deepEqual(original, expectedOriginal); |
| 148 | + // Read the new data at D10:E10 |
| 149 | + alasql( |
| 150 | + 'SELECT * FROM XLSX("' + |
| 151 | + __dirname + |
| 152 | + '/test107-B-self.xlsx", {headers:true, sheetid:"Sheet 1", range:"D10:E11"})', |
| 153 | + [], |
| 154 | + function (updated) { |
| 155 | + var expectedUpdated = [{value: 999, status: 'updated'}]; |
| 156 | + assert.deepEqual(updated, expectedUpdated); |
| 157 | + done(); |
| 158 | + } |
| 159 | + ); |
| 160 | + } |
| 161 | + ); |
| 162 | + } |
| 163 | + ); |
| 164 | + }); |
| 165 | + |
| 166 | + it('5. Add data to new sheet in existing file', function (done) { |
| 167 | + var newSheetData = [ |
| 168 | + {col1: 'A', col2: 'B'}, |
| 169 | + {col1: 'C', col2: 'D'}, |
| 170 | + ]; |
| 171 | + |
| 172 | + alasql( |
| 173 | + 'SELECT * INTO XLSX("' + |
| 174 | + __dirname + |
| 175 | + '/test107-B-newsheet.xlsx", {sourcefilename:"' + |
| 176 | + __dirname + |
| 177 | + '/test107-B-base.xlsx", sheetid:"NewSheet", range:"A1", headers:true}) FROM ?', |
| 178 | + [newSheetData], |
| 179 | + function (res) { |
| 180 | + assert(res == 1); |
| 181 | + assert(fs.existsSync(__dirname + '/test107-B-newsheet.xlsx')); |
| 182 | + // Verify the new sheet has the correct data |
| 183 | + alasql( |
| 184 | + 'SELECT * FROM XLSX("' + |
| 185 | + __dirname + |
| 186 | + '/test107-B-newsheet.xlsx", {headers:true, sheetid:"NewSheet"})', |
| 187 | + [], |
| 188 | + function (result) { |
| 189 | + assert.deepEqual(result, newSheetData); |
| 190 | + // Also verify original sheet still exists |
| 191 | + alasql( |
| 192 | + 'SELECT * FROM XLSX("' + |
| 193 | + __dirname + |
| 194 | + '/test107-B-newsheet.xlsx", {headers:true, sheetid:"Sheet 1"})', |
| 195 | + [], |
| 196 | + function (original) { |
| 197 | + assert.equal(original.length, 3); |
| 198 | + assert.equal(original[0].a, 1); |
| 199 | + done(); |
| 200 | + } |
| 201 | + ); |
| 202 | + } |
| 203 | + ); |
| 204 | + } |
| 205 | + ); |
| 206 | + }); |
| 207 | + |
| 208 | + it('6. Test with various range positions (AA5)', function (done) { |
| 209 | + var testData = [{test: 'value'}]; |
| 210 | + |
| 211 | + // Test range AA5 (multi-letter column) |
| 212 | + alasql( |
| 213 | + 'SELECT * INTO XLSX("' + |
| 214 | + __dirname + |
| 215 | + '/test107-B-range-AA5.xlsx", {sourcefilename:"' + |
| 216 | + __dirname + |
| 217 | + '/test107-B-base.xlsx", sheetid:"Sheet 1", range:"AA5", headers:false}) FROM ?', |
| 218 | + [testData], |
| 219 | + function (res) { |
| 220 | + assert(res == 1); |
| 221 | + assert(fs.existsSync(__dirname + '/test107-B-range-AA5.xlsx')); |
| 222 | + // Read back the data at AA5 (column 27) |
| 223 | + alasql( |
| 224 | + 'SELECT * FROM XLSX("' + |
| 225 | + __dirname + |
| 226 | + '/test107-B-range-AA5.xlsx", {headers:false, sheetid:"Sheet 1", range:"AA5:AA5"})', |
| 227 | + [], |
| 228 | + function (result) { |
| 229 | + var expectedResult = [{AA: 'value'}]; |
| 230 | + assert.deepEqual(result, expectedResult); |
| 231 | + done(); |
| 232 | + } |
| 233 | + ); |
| 234 | + } |
| 235 | + ); |
| 236 | + }); |
| 237 | + |
| 238 | + it('7. Test async/promise flow for sourcefilename and range', async function () { |
| 239 | + // Create test data |
| 240 | + var testData = [ |
| 241 | + {name: 'Alice', score: 95}, |
| 242 | + {name: 'Bob', score: 87}, |
| 243 | + ]; |
| 244 | + |
| 245 | + // Write initial file using promise |
| 246 | + await alasql.promise( |
| 247 | + 'SELECT * INTO XLSX("' + __dirname + '/test107-B-async.xlsx", {headers:true}) FROM ?', |
| 248 | + [testData] |
| 249 | + ); |
| 250 | + |
| 251 | + // Update file at specific range using promise |
| 252 | + var updateData = [{extra: 'data', value: 123}]; |
| 253 | + await alasql.promise( |
| 254 | + 'SELECT * INTO XLSX("' + |
| 255 | + __dirname + |
| 256 | + '/test107-B-async.xlsx", {sourcefilename:"' + |
| 257 | + __dirname + |
| 258 | + '/test107-B-async.xlsx", sheetid:"Sheet 1", range:"D5", headers:true}) FROM ?', |
| 259 | + [updateData] |
| 260 | + ); |
| 261 | + |
| 262 | + // Read back and verify using promise |
| 263 | + var original = await alasql.promise( |
| 264 | + 'SELECT * FROM XLSX("' + |
| 265 | + __dirname + |
| 266 | + '/test107-B-async.xlsx", {headers:true, sheetid:"Sheet 1", range:"A1:B3"})', |
| 267 | + [] |
| 268 | + ); |
| 269 | + assert.deepEqual(original, testData); |
| 270 | + |
| 271 | + // Read the updated data |
| 272 | + var updated = await alasql.promise( |
| 273 | + 'SELECT * FROM XLSX("' + |
| 274 | + __dirname + |
| 275 | + '/test107-B-async.xlsx", {headers:true, sheetid:"Sheet 1", range:"D5:E6"})', |
| 276 | + [] |
| 277 | + ); |
| 278 | + assert.deepEqual(updated, updateData); |
| 279 | + }); |
| 280 | + |
| 281 | + it('8. Test promise-based flow with new sheet creation', async function () { |
| 282 | + var sheet1Data = [{id: 1, value: 'first'}]; |
| 283 | + var sheet2Data = [{id: 2, value: 'second'}]; |
| 284 | + |
| 285 | + // Create initial file |
| 286 | + await alasql.promise( |
| 287 | + 'SELECT * INTO XLSX("' + __dirname + '/test107-B-promise.xlsx", {headers:true}) FROM ?', |
| 288 | + [sheet1Data] |
| 289 | + ); |
| 290 | + |
| 291 | + // Add new sheet using sourcefilename |
| 292 | + await alasql.promise( |
| 293 | + 'SELECT * INTO XLSX("' + |
| 294 | + __dirname + |
| 295 | + '/test107-B-promise.xlsx", {sourcefilename:"' + |
| 296 | + __dirname + |
| 297 | + '/test107-B-promise.xlsx", sheetid:"Sheet2", range:"A1", headers:true}) FROM ?', |
| 298 | + [sheet2Data] |
| 299 | + ); |
| 300 | + |
| 301 | + // Verify Sheet 1 |
| 302 | + var result1 = await alasql.promise( |
| 303 | + 'SELECT * FROM XLSX("' + |
| 304 | + __dirname + |
| 305 | + '/test107-B-promise.xlsx", {headers:true, sheetid:"Sheet 1"})', |
| 306 | + [] |
| 307 | + ); |
| 308 | + assert.deepEqual(result1, sheet1Data); |
| 309 | + |
| 310 | + // Verify Sheet 2 |
| 311 | + var result2 = await alasql.promise( |
| 312 | + 'SELECT * FROM XLSX("' + |
| 313 | + __dirname + |
| 314 | + '/test107-B-promise.xlsx", {headers:true, sheetid:"Sheet2"})', |
| 315 | + [] |
| 316 | + ); |
| 317 | + assert.deepEqual(result2, sheet2Data); |
| 318 | + }); |
| 319 | + |
| 320 | + // Cleanup test files after all tests |
| 321 | + after(function () { |
| 322 | + var testFiles = [ |
| 323 | + 'test107-B-base.xlsx', |
| 324 | + 'test107-B-updated.xlsx', |
| 325 | + 'test107-B-no-headers.xlsx', |
| 326 | + 'test107-B-self.xlsx', |
| 327 | + 'test107-B-newsheet.xlsx', |
| 328 | + 'test107-B-range-AA5.xlsx', |
| 329 | + 'test107-B-async.xlsx', |
| 330 | + 'test107-B-promise.xlsx', |
| 331 | + ]; |
| 332 | + |
| 333 | + testFiles.forEach(function (file) { |
| 334 | + var filePath = __dirname + '/' + file; |
| 335 | + if (fs.existsSync(filePath)) { |
| 336 | + fs.unlinkSync(filePath); |
| 337 | + } |
| 338 | + }); |
| 339 | + }); |
| 340 | + } |
| 341 | +}); |
0 commit comments