-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Properly assigning styles by deep copy #722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,21 @@ | ||
| 'use strict'; | ||
|
|
||
| var verquire = require('../utils/verquire'); | ||
| var testutils = require('../utils/index'); | ||
| var fs = require('fs'); | ||
| var expect = require('chai').expect; | ||
| const verquire = require('../utils/verquire'); | ||
| const testutils = require('../utils/index'); | ||
| const fs = require('fs'); | ||
| const expect = require('chai').expect; | ||
|
|
||
| var Excel = verquire('excel'); | ||
| const Excel = verquire('excel'); | ||
|
|
||
| var TEST_FILE_NAME = './spec/out/wb.test.xlsx'; | ||
| const TEST_FILE_NAME = './spec/out/wb.test.xlsx'; | ||
|
|
||
| // need some architectural changes to make stream read work properly | ||
| // because of: shared strings, sheet names, etc are not read in guaranteed order | ||
| describe('WorkbookReader', function() { | ||
| describe('Serialise', function() { | ||
| it('xlsx file', function() { | ||
| this.timeout(10000); | ||
| var wb = testutils.createTestBook(new Excel.Workbook(), 'xlsx'); | ||
| const wb = testutils.createTestBook(new Excel.Workbook(), 'xlsx'); | ||
|
|
||
| return wb.xlsx.writeFile(TEST_FILE_NAME) | ||
| .then(function() { | ||
|
|
@@ -27,7 +27,7 @@ describe('WorkbookReader', function() { | |
| describe('#readFile', function() { | ||
| describe('Row limit', function() { | ||
| it('should bail out if the file contains more rows than the limit', function() { | ||
| var workbook = new Excel.Workbook(); | ||
| const workbook = new Excel.Workbook(); | ||
| // The Fibonacci sheet has 19 rows | ||
| return workbook.xlsx.readFile('./spec/integration/data/fibonacci.xlsx', {maxRows: 10}) | ||
| .then(function() { | ||
|
|
@@ -39,7 +39,7 @@ describe('WorkbookReader', function() { | |
|
|
||
| it('should fail fast on a huge file', function() { | ||
| this.timeout(20000); | ||
| var workbook = new Excel.Workbook(); | ||
| const workbook = new Excel.Workbook(); | ||
| return workbook.xlsx.readFile('./spec/integration/data/huge.xlsx', {maxRows: 100}) | ||
| .then(function() { | ||
| throw new Error('Promise unexpectedly fulfilled'); | ||
|
|
@@ -49,7 +49,7 @@ describe('WorkbookReader', function() { | |
| }); | ||
|
|
||
| it('should parse fine if the limit is not exceeded', function() { | ||
| var workbook = new Excel.Workbook(); | ||
| const workbook = new Excel.Workbook(); | ||
| return workbook.xlsx.readFile('./spec/integration/data/fibonacci.xlsx', {maxRows: 20}); | ||
| }); | ||
| }); | ||
|
|
@@ -58,7 +58,7 @@ describe('WorkbookReader', function() { | |
| describe('#read', function() { | ||
| describe('Row limit', function() { | ||
| it('should bail out if the file contains more rows than the limit', function() { | ||
| var workbook = new Excel.Workbook(); | ||
| const workbook = new Excel.Workbook(); | ||
| // The Fibonacci sheet has 19 rows | ||
| return workbook.xlsx.read(fs.createReadStream('./spec/integration/data/fibonacci.xlsx'), {maxRows: 10}) | ||
| .then(function() { | ||
|
|
@@ -69,16 +69,39 @@ describe('WorkbookReader', function() { | |
| }); | ||
|
|
||
| it('should parse fine if the limit is not exceeded', function() { | ||
| var workbook = new Excel.Workbook(); | ||
| const workbook = new Excel.Workbook(); | ||
| return workbook.xlsx.read(fs.createReadStream('./spec/integration/data/fibonacci.xlsx'), {maxRows: 20}); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('edit styles in existing file', function(){ | ||
| beforeEach(function(){ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why? I quite like moving things to async/await. the test suite runs on node, so there's no transpiling here
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we currently support node v6 :(
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. damn, right you are :( |
||
| this.wb = new Excel.Workbook(); | ||
| return this.wb.xlsx.readFile('./spec/integration/data/test-row-styles.xlsx'); | ||
| }); | ||
|
|
||
| it('edit styles of single row instead of all', function () { | ||
| const ws = this.wb.getWorksheet(1); | ||
|
|
||
| ws.eachRow((row, rowNo) => { | ||
| rowNo % 5 === 0 && (row.font = {color: {argb: '00ff00'}}) | ||
| }); | ||
|
|
||
| expect(ws.getRow(3).font.color.argb).to.be.equal(ws.getRow(6).font.color.argb); | ||
| expect(ws.getRow(6).font.color.argb).to.be.equal(ws.getRow(9).font.color.argb); | ||
| expect(ws.getRow(9).font.color.argb).to.be.equal(ws.getRow(12).font.color.argb); | ||
| expect(ws.getRow(12).font.color.argb).not.to.be.equal(ws.getRow(15).font.color.argb); | ||
| expect(ws.getRow(15).font.color.argb).not.to.be.equal(ws.getRow(18).font.color.argb); | ||
| expect(ws.getRow(15).font.color.argb).to.be.equal(ws.getRow(10).font.color.argb); | ||
| expect(ws.getRow(10).font.color.argb).to.be.equal(ws.getRow(5).font.color.argb); | ||
| }) | ||
| }); | ||
|
|
||
| describe('with a spreadsheet that contains formulas', function() { | ||
| before(function() { | ||
| var testContext = this; | ||
| var workbook = new Excel.Workbook(); | ||
| const testContext = this; | ||
| const workbook = new Excel.Workbook(); | ||
| return workbook.xlsx.read(fs.createReadStream('./spec/integration/data/formulas.xlsx')) | ||
| .then(function() { | ||
| testContext.worksheet = workbook.getWorksheet(); | ||
|
|
@@ -130,8 +153,8 @@ describe('WorkbookReader', function() { | |
|
|
||
| describe('with a spreadsheet that contains a shared string with an escaped underscore', function() { | ||
| before(function() { | ||
| var testContext = this; | ||
| var workbook = new Excel.Workbook(); | ||
| const testContext = this; | ||
| const workbook = new Excel.Workbook(); | ||
| return workbook.xlsx.read(fs.createReadStream('./spec/integration/data/shared_string_with_escape.xlsx')) | ||
| .then(function() { | ||
| testContext.worksheet = workbook.getWorksheet(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix is here ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of this, since there's a couple of subtle ways this can fail or lose things depending on the shape of the object. do we know what values each key of
value.stylecan hold? is it just a flat object of"some string": "another string"or can it also hold numbers, arrays, functions or other objects?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is only object that keep configuration of styles
there aren't any functions or getters/setters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gotcha. Can you help me understand the performance impact here?
JSON.parse(JSON.stringify())is quite slow and it would suck if this actually runs for all (or most) rows. Also, it increases the memory overhead a bit. How many rows will have this property?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
personally I think it's much better to write style cloning function in utils ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using JSON is indeed pretty slow to copy things. You could use e.g., https://github.com/davidmarkclements/rfdc for now (I would normally just recommend to use object spread but that's not available in versions below 8 and slow before v.10 or v.11 😄).
@alubbe the current API does not seem to have performance in mind. If the user changes any input that should be registered in a clean way so all internals can work side effect free. This does not seem to be possible without the penalty here. Using getters and setters might reduce the overhead by only copying values that have to be changed but as far as I see it that would probably be pretty brittle with the current code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree - let's merge it and then actually benchmark why this library is slow and fix those, as opposed to pre-optimizing a bugfix