@@ -6632,3 +6632,105 @@ func TestParseToken(t *testing.T) {
66326632 efp.Token {TSubType : efp .TokenSubTypeRange , TValue : "1A" }, nil , nil ,
66336633 ).Error ())
66346634}
6635+
6636+ func TestCalcCellValueCache (t * testing.T ) {
6637+ t .Run ("for_calc_call_value_with_cache" , func (t * testing.T ) {
6638+ f := NewFile ()
6639+ assert .NoError (t , f .SetCellValue ("Sheet1" , "A1" , 40 ))
6640+ assert .NoError (t , f .SetCellValue ("Sheet1" , "A2" , 50 ))
6641+ assert .NoError (t , f .SetCellFormula ("Sheet1" , "A3" , "A1+A2" ))
6642+
6643+ result1 , err := f .CalcCellValue ("Sheet1" , "A3" )
6644+ assert .NoError (t , err )
6645+ assert .Equal (t , "90" , result1 )
6646+
6647+ result2 , err := f .CalcCellValue ("Sheet1" , "A3" )
6648+ assert .NoError (t , err )
6649+ assert .Equal (t , result1 , result2 , "cached result should be consistent" )
6650+
6651+ assert .NoError (t , f .SetCellValue ("Sheet1" , "A1" , 60 ))
6652+
6653+ result3 , err := f .CalcCellValue ("Sheet1" , "A3" )
6654+ assert .NoError (t , err )
6655+ assert .Equal (t , "110" , result3 )
6656+ assert .NotEqual (t , result1 , result3 , "result should be updated after cache clear" )
6657+ })
6658+ t .Run ("for_calc_call_value_with_multiple_dependent_cells" , func (t * testing.T ) {
6659+ f := NewFile ()
6660+ assert .NoError (t , f .SetCellValue ("Sheet1" , "A1" , 10 ))
6661+ assert .NoError (t , f .SetCellValue ("Sheet1" , "A2" , 10 ))
6662+ assert .NoError (t , f .SetCellFormula ("Sheet1" , "A3" , "A1+A2" ))
6663+ assert .NoError (t , f .SetCellFormula ("Sheet1" , "A4" , "A3*3" ))
6664+ assert .NoError (t , f .SetCellFormula ("Sheet1" , "A5" , "A3+A4" ))
6665+
6666+ result3 , err := f .CalcCellValue ("Sheet1" , "A3" )
6667+ assert .NoError (t , err )
6668+ assert .Equal (t , "20" , result3 )
6669+
6670+ result4 , err := f .CalcCellValue ("Sheet1" , "A4" )
6671+ assert .NoError (t , err )
6672+ assert .Equal (t , "60" , result4 )
6673+
6674+ result5 , err := f .CalcCellValue ("Sheet1" , "A5" )
6675+ assert .NoError (t , err )
6676+ assert .Equal (t , "80" , result5 )
6677+
6678+ assert .NoError (t , f .SetCellValue ("Sheet1" , "A1" , 20 ))
6679+
6680+ newResult3 , err := f .CalcCellValue ("Sheet1" , "A3" )
6681+ assert .NoError (t , err )
6682+ assert .Equal (t , "30" , newResult3 )
6683+ assert .NotEqual (t , result3 , newResult3 , "A3 should be updated" )
6684+
6685+ newResult5 , err := f .CalcCellValue ("Sheet1" , "A5" )
6686+ assert .NoError (t , err )
6687+ assert .Equal (t , "120" , newResult5 )
6688+ assert .NotEqual (t , result5 , newResult5 , "A5 should be updated" )
6689+ })
6690+ t .Run ("for_clear_calculation_cache" , func (t * testing.T ) {
6691+ f := NewFile ()
6692+ assert .NoError (t , f .SetCellValue ("Sheet1" , "A1" , 10 ))
6693+ assert .NoError (t , f .SetCellFormula ("Sheet1" , "A2" , "A1*2" ))
6694+
6695+ result1 , err := f .CalcCellValue ("Sheet1" , "A2" )
6696+ assert .NoError (t , err )
6697+ assert .Equal (t , "20" , result1 )
6698+
6699+ result2 , err := f .CalcCellValue ("Sheet1" , "A2" )
6700+ assert .NoError (t , err )
6701+ assert .Equal (t , result1 , result2 , "results should be consistent from cache" )
6702+
6703+ cases := []struct {
6704+ name string
6705+ fn func () error
6706+ }{
6707+ {"SetCellValue" , func () error { return f .SetCellValue ("Sheet1" , "B1" , 100 ) }},
6708+ {"SetCellInt" , func () error { return f .SetCellInt ("Sheet1" , "B2" , 200 ) }},
6709+ {"SetCellUint" , func () error { return f .SetCellUint ("Sheet1" , "B3" , 300 ) }},
6710+ {"SetCellFloat" , func () error { return f .SetCellFloat ("Sheet1" , "B4" , 3.14 , 2 , 64 ) }},
6711+ {"SetCellStr" , func () error { return f .SetCellStr ("Sheet1" , "B5" , "test" ) }},
6712+ {"SetCellBool" , func () error { return f .SetCellBool ("Sheet1" , "B6" , true ) }},
6713+ {"SetCellDefault" , func () error { return f .SetCellDefault ("Sheet1" , "B7" , "default" ) }},
6714+ {"SetCellFormula" , func () error { return f .SetCellFormula ("Sheet1" , "B8" , "=1+1" ) }},
6715+ {"SetCellHyperLink" , func () error {
6716+ return f .SetCellHyperLink ("Sheet1" , "B9" , "https://github.com/xuri/excelize" , "External" )
6717+ }},
6718+ {"SetCellRichText" , func () error {
6719+ runs := []RichTextRun {{Text : "Rich" , Font : & Font {Bold : true }}}
6720+ return f .SetCellRichText ("Sheet1" , "B10" , runs )
6721+ }},
6722+ {"SetSheetRow" , func () error { return f .SetSheetRow ("Sheet1" , "C1" , & []interface {}{1 , 2 , 3 }) }},
6723+ {"SetSheetCol" , func () error { return f .SetSheetCol ("Sheet1" , "D1" , & []interface {}{4 , 5 , 6 }) }},
6724+ }
6725+ for _ , tc := range cases {
6726+ t .Run (tc .name , func (t * testing.T ) {
6727+ _ , err := f .CalcCellValue ("Sheet1" , "A2" )
6728+ assert .NoError (t , err )
6729+ assert .NoError (t , tc .fn ())
6730+ result , err := f .CalcCellValue ("Sheet1" , "A2" )
6731+ assert .NoError (t , err )
6732+ assert .Equal (t , "20" , result , "calculation should still work after cache clear" )
6733+ })
6734+ }
6735+ })
6736+ }
0 commit comments