UNPKG

react-microspreadsheet

Version:

A pluggable spreadsheet component.

359 lines (294 loc) 12.8 kB
Mousetrap = require 'mousetrap' React = require 'react/addons' testUtils = React.addons.TestUtils expect = chai.expect Spreadsheet = require '../src/Spreadsheet.coffee' utils = reset: -> React.unmountComponentAtNode($('div#test-node')[0]) $('div#test-node').remove() testNode: -> testNode = $('<div>').attr('id', 'test-node') $('body').append(testNode) testNode.empty() return testNode[0] describe 'basic', -> this.timeout 50000 describe 'text cells', -> before (done) -> cells = [ ['','123','','123'] ['asd','','sad',''] ['','as','','sd'] ['das','','123',''] ] React.renderComponent Spreadsheet(cells: cells), utils.testNode(), done after utils.reset it 'renders the table', (done) -> expect($('table.microspreadsheet')).to.exist done() it 'renders the rows and cells at the right places', (done) -> cells = [] for row in $('.microspreadsheet tr') rowArray = [] for cell in $(row).find('td') rowArray.push $(cell).text() cells.push rowArray expect(cells[0]).to.eql ['', 'A', 'B', 'C', 'D'] expect(cells[1]).to.eql ['1', '', '123', '', '123'] expect(cells[4]).to.eql ['4', 'das', '', '123', ''] done() describe 'formulas (refs, expressions and sum() with matrixes)', (done) -> before (done) -> cells = [ ['=A2','123'] ['7','=B1+A2'] ['=2+B3','=1+2'] ['=SUM(A1,A2)','=sUm(A1:B2)'] ] React.renderComponent Spreadsheet(cells: cells), utils.testNode(), done it 'renders the table', (done) -> expect($('table.microspreadsheet')).to.exist done() it 'renders the rows and cells with the right values', (done) -> cells = [] for row in $('.microspreadsheet tr') rowArray = [] for cell in $(row).find('td') rowArray.push $(cell).text() cells.push rowArray expect(cells[1]).to.eql ['1', '7', '123'] expect(cells[2]).to.eql ['2', '7', '130'] expect(cells[3]).to.eql ['3', '5', '3'] expect(cells[4]).to.eql ['4', '14', '267'] done() describe 'dbclick, edit, click outside', -> sheet = null secondCell = null input = null before (done) -> cells = [ ['44','123'] ['7',''] ['=SUM(A1,A2)','=sUm(A1:B2)'] ] sheet = React.renderComponent Spreadsheet(cells: cells), utils.testNode(), done after utils.reset it 'finds the second cell and starts editing', (done) -> secondCell = testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[1] span = testUtils.findRenderedDOMComponentWithTag(secondCell, 'span') testUtils.Simulate.doubleClick(span) expect($('.microspreadsheet .cell input')[0]).to.exist expect($('.microspreadsheet .cell input').val()).to.eql '123' done() it 'changes its value', (done) -> input = testUtils.findRenderedDOMComponentWithTag(secondCell, 'input') testUtils.Simulate.change(input, {target: {value: '16'}}) expect($('.microspreadsheet .cell input').val()).to.eql '16' done() it 'click at other cell and the table recalculates', (done) -> $('.microspreadsheet .cell span').eq(3).click() expect($('.microspreadsheet .cell input').length).to.eql 0 expect($('.microspreadsheet .cell').eq(1).text()).to.eql '16' expect($('.microspreadsheet .cell').eq(4).text()).to.eql '51' expect($('.microspreadsheet .cell').eq(5).text()).to.eql '67' done() describe 'change it from outside', -> sheet = null before (done) -> cells = [ ['=A2','123'] ['7','=B1+A2'] ['=2+B3','=1+2'] ['=SUM(A1,A2)','=sUm(A1:B2)'] ] sheet = React.renderComponent Spreadsheet(cells: cells), utils.testNode(), done after utils.reset it 'renders the rows and cells with the right values', (done) -> cells = [] for row in $('.microspreadsheet tr') rowArray = [] for cell in $(row).find('td') rowArray.push $(cell).text() cells.push rowArray expect(cells[1]).to.eql ['1', '7', '123'] expect(cells[2]).to.eql ['2', '7', '130'] expect(cells[3]).to.eql ['3', '5', '3'] expect(cells[4]).to.eql ['4', '14', '267'] done() it 'changes when the `cells` prop changes', (done) -> cells = [ ['x3', '=A1'] ['', ''] ['', ''] ['', ''] ['', ''] ['b', 'c'] ] sheet.setProps cells: cells cells = [] for row in $('.microspreadsheet tr') rowArray = [] for cell in $(row).find('td') rowArray.push $(cell).text() cells.push rowArray expect(cells[1]).to.eql ['1', 'x3', 'x3'] expect(cells[2]).to.eql ['2', '', ''] expect(cells[3]).to.eql ['3', '', ''] expect(cells[4]).to.eql ['4', '', ''] expect(cells[5]).to.eql ['5', '', ''] expect(cells[6]).to.eql ['6', 'b', 'c'] done() describe 'click to add reference', -> sheet = null secondCell = null input = null before (done) -> cells = [ ['5','2'] ['7','9'] ] sheet = React.renderComponent Spreadsheet(cells: cells), utils.testNode(), done after utils.reset it 'finds the second cell and starts editing', (done) -> secondCell = testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[1] span = testUtils.findRenderedDOMComponentWithTag(secondCell, 'span') testUtils.Simulate.doubleClick(span) done() it 'adds a "="', (done) -> input = testUtils.findRenderedDOMComponentWithTag(secondCell, 'input') testUtils.Simulate.change(input, {target: {value: '='}}) expect($('.microspreadsheet .cell input').val()).to.eql '=' done() it 'clicks at other cell and add its addr to the input', (done) -> fourthCell = testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[3] span = testUtils.findRenderedDOMComponentWithTag(fourthCell, 'span') testUtils.Simulate.click(span) expect($('.microspreadsheet .cell input').val()).to.eql '=B2' done() it 'clicks at another cell and replace the previous one', (done) -> thirdCell = testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[2] span = testUtils.findRenderedDOMComponentWithTag(thirdCell, 'span') testUtils.Simulate.click(span) expect($('.microspreadsheet .cell input').val()).to.eql '=A2' done() it 'recalculates when enter is pressed', (done) -> KeyEvent.simulate(0, 13) expect($('.microspreadsheet .cell input').length).to.eql 0 expect($('.microspreadsheet .cell').eq(1).text()).to.eql '7' expect($('.microspreadsheet .cell').eq(2).text()).to.eql '7' expect($('.microspreadsheet .cell').eq(3).text()).to.eql '9' done() describe 'movement and keyboard shortcuts', -> before (done) -> cells = [ ['5','2'] ['7','9'] ] React.renderComponent Spreadsheet(cells: cells), utils.testNode(), done after utils.reset it 'starts at the first cell', (done) -> expect($('.microspreadsheet .cell').eq(0).hasClass('selected')).to.eql true done() it 'goes right', (done) -> KeyEvent.simulate(0, 39) expect($('.microspreadsheet .cell').eq(1).hasClass('selected')).to.eql true done() it 'deletes the content inside', (done) -> KeyEvent.simulate(0, 46) expect($('.microspreadsheet .cell span').eq(1).text()).to.eql '' done() it 'does not go up', (done) -> KeyEvent.simulate(0, 38) expect($('.microspreadsheet .cell').eq(1).hasClass('selected')).to.eql true done() it 'goes down', (done) -> KeyEvent.simulate(0, 40) expect($('.microspreadsheet .cell').eq(3).hasClass('selected')).to.eql true done() it 'starts editing with a keypress (also replacing the text field with the corresponding char)', (done) -> KeyEvent.simulate(80, 80) expect($('.microspreadsheet .cell').eq(3).hasClass('selected')).to.eql true expect($('.microspreadsheet .cell input')).to.have.length 1 expect($('.microspreadsheet .cell input').val()).to.eql 'P' done() it 'cancels the edit', (done) -> KeyEvent.simulate(0, 27) expect($('.microspreadsheet .cell').eq(3).text()).to.eql '9' done() describe 'undo, redo', -> before (done) -> cells = [ ['a', 'b'] ['c', 'd'] ] React.renderComponent Spreadsheet(cells: cells), utils.testNode(), done after utils.reset it 'starts editing with a keypress (also replacing the text field with the corresponding char)', (done) -> KeyEvent.simulate(81, 81) expect($('.microspreadsheet .cell input').val()).to.eql 'Q' done() it 'saves the edit', (done) -> KeyEvent.simulate(0, 13) expect($('.microspreadsheet .cell span').length).to.eql 4 expect($('.microspreadsheet .cell span').eq(0).text()).to.eql 'Q' done() it 'undoes the edit', (done) -> KeyEvent.simulate(90, 90, ['ctrl']) expect($('.microspreadsheet .cell span').eq(0).text()).to.eql 'a' done() it 'redoes the edit', (done) -> KeyEvent.simulate(89, 89, ['ctrl']) expect($('.microspreadsheet .cell span').eq(0).text()).to.eql 'Q' done() describe 'multi select', -> sheet = null before (done) -> cells = [ ['', 'b'] ['a', ''] ['', ''] ['', ''] ] sheet = React.renderComponent Spreadsheet(cells: cells), utils.testNode(), done after utils.reset it 'starts selecting', (done) -> first = testUtils.findRenderedDOMComponentWithTag(testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[0], 'span') testUtils.Simulate.mouseDown(first) expect($('.microspreadsheet .cell').eq(0).hasClass('multi-selected')).to.eql false expect($('.microspreadsheet .cell').eq(1).hasClass('multi-selected')).to.eql false expect($('.microspreadsheet .cell').eq(2).hasClass('multi-selected')).to.eql false expect($('.microspreadsheet .cell').eq(3).hasClass('multi-selected')).to.eql false done() it 'moves transversally', (done) -> first = testUtils.findRenderedDOMComponentWithTag(testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[0], 'span') third = testUtils.findRenderedDOMComponentWithTag(testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[2], 'span') testUtils.SimulateNative.mouseOut(first, {relatedTarget: $('.microspreadsheet .cell').eq(2)[0]}) testUtils.SimulateNative.mouseOver(third, {relatedTarget: $('.microspreadsheet .cell').eq(0)[0]}) expect($('.microspreadsheet .cell').eq(0).hasClass('multi-selected')).to.eql true expect($('.microspreadsheet .cell').eq(1).hasClass('multi-selected')).to.eql true expect($('.microspreadsheet .cell').eq(2).hasClass('multi-selected')).to.eql true expect($('.microspreadsheet .cell').eq(3).hasClass('multi-selected')).to.eql false done() it 'moves back and the selection adjusts', (done) -> third = testUtils.findRenderedDOMComponentWithTag(testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[2], 'span') second = testUtils.findRenderedDOMComponentWithTag(testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[1], 'span') testUtils.SimulateNative.mouseOut(third, {relatedTarget: $('.microspreadsheet .cell').eq(1)[0]}) testUtils.SimulateNative.mouseOver(second, {relatedTarget: $('.microspreadsheet .cell').eq(2)[0]}) expect($('.microspreadsheet .cell').eq(0).hasClass('multi-selected')).to.eql true expect($('.microspreadsheet .cell').eq(1).hasClass('multi-selected')).to.eql true expect($('.microspreadsheet .cell').eq(2).hasClass('multi-selected')).to.eql false done() it 'stops selecting and the selection continues', (done) -> second = testUtils.findRenderedDOMComponentWithTag(testUtils.scryRenderedDOMComponentsWithClass(sheet, 'cell')[1], 'span') testUtils.Simulate.mouseUp(second) expect($('.microspreadsheet .cell').eq(0).hasClass('multi-selected')).to.eql true expect($('.microspreadsheet .cell').eq(1).hasClass('multi-selected')).to.eql true expect($('.microspreadsheet .cell').eq(2).hasClass('multi-selected')).to.eql false done() it 'deletes everything under the selection', (done) -> KeyEvent.simulate(0, 46) expect($('.microspreadsheet .cell').eq(0).text()).to.eql '' expect($('.microspreadsheet .cell').eq(1).text()).to.eql '' expect($('.microspreadsheet .cell').eq(2).text()).to.eql 'a' done()