#!/usr/bin/env python3 import unittest import ixion class DocumentTest(unittest.TestCase): def setUp(self): self.doc = ixion.Document() def test_append_sheets(self): tests = ( "Normal", # normal name "First Sheet", # white space "Laura's", # single quote '"Quoted"' # double quote ) sheets = [] for test in tests: sh = self.doc.append_sheet(test) sheets.append(sh) for test, sheet in zip(tests, sheets): self.assertEqual(test, sheet.name) self.assertEqual(tests, self.doc.sheet_names) for i, test in enumerate(tests): # get sheet by index. sh = self.doc.get_sheet(i) self.assertEqual(test, sh.name) for test in tests: # get sheet by name. sh = self.doc.get_sheet(test) self.assertEqual(test, sh.name) try: sheets[0].name = "Try to change sheet name" self.assertTrue(False, "sheet name attribute should not be writable.") except AttributeError: pass # AttributeError is expected when attempting to overwrite sheet name attribute. except: self.assertTrue(False, "Wrong exception has been raised") # Trying to insert a new sheet with an existing name should fail. try: sh = self.doc.append_sheet(tests[0]) self.assertTrue(False, "Trying to insert a new sheet with an existing sheet name should fail") except ixion.DocumentError: # This is expected. pass def test_numeric_cell_input(self): sh1 = self.doc.append_sheet("Data") # Empty cell should yield a value of 0.0. check_val = sh1.get_numeric_value(0, 0) self.assertEqual(0.0, check_val) tests = ( # row, column, value (3, 1, 11.2), (4, 1, 12.0), (6, 2, -12.0), (6, 3, 0.0) ) for test in tests: sh1.set_numeric_cell(test[0], test[1], test[2]) # row, column, value check_val = sh1.get_numeric_value(column=test[1], row=test[0]) # swap row and column self.assertEqual(test[2], check_val) def test_string_cell_input(self): sh1 = self.doc.append_sheet("Data") # Empty cell should yield an empty string. check_val = sh1.get_string_value(0, 0) self.assertEqual("", check_val) tests = ( # row, column, value (0, 0, "normal string"), # normal string (1, 0, "A1+B1"), # string that looks like a formula expression (2, 0, "'single quote'"), # single quote (3, 0, "80's music"), # single quote (4, 0, '"The" Music in the 80\'s'), # single and double quotes mixed ) for test in tests: sh1.set_string_cell(test[0], test[1], test[2]) # row, column, value check_val = sh1.get_string_value(column=test[1], row=test[0]) # swap row and column self.assertEqual(test[2], check_val) def test_formula_cell_input(self): sh1 = self.doc.append_sheet("Data") sh1.set_formula_cell(0, 0, "12*3") try: val = sh1.get_numeric_value(0, 0) self.assertTrue(False, "TypeError should have been raised") except TypeError: # TypeError is expected when trying to fetch numeric value from # formula cell before it is calculated. pass self.doc.calculate() val = sh1.get_numeric_value(0, 0) self.assertEqual(12*3, val) def test_formula_cell_recalc(self): sh1 = self.doc.append_sheet("Data") sh1.set_numeric_cell(0, 0, 1.0) sh1.set_numeric_cell(1, 0, 2.0) sh1.set_numeric_cell(2, 0, 4.0) sh1.set_formula_cell(3, 0, "SUM(A1:A3)") # initial calculation self.doc.calculate() val = sh1.get_numeric_value(3, 0) self.assertEqual(7.0, val) # recalculation sh1.set_numeric_cell(1, 0, 8.0) self.doc.calculate() val = sh1.get_numeric_value(3, 0) self.assertEqual(13.0, val) # add another formula cell and recalc. sh1.set_formula_cell(0, 1, "A1+15") sh1.set_numeric_cell(0, 0, 0.0) self.doc.calculate() val = sh1.get_numeric_value(0, 1) self.assertEqual(15.0, val) val = sh1.get_numeric_value(3, 0) self.assertEqual(12.0, val) def test_formula_cell_recalc2(self): sh1 = self.doc.append_sheet("Data") sh1.set_numeric_cell(4, 1, 12.0) # B5 sh1.set_formula_cell(5, 1, "B5*2") sh1.set_formula_cell(6, 1, "B6+10") self.doc.calculate() val = sh1.get_numeric_value(4, 1) self.assertEqual(12.0, val) val = sh1.get_numeric_value(5, 1) self.assertEqual(24.0, val) val = sh1.get_numeric_value(6, 1) self.assertEqual(34.0, val) # Delete B5 and check. sh1.empty_cell(4, 1) self.doc.calculate() val = sh1.get_numeric_value(4, 1) self.assertEqual(0.0, val) val = sh1.get_numeric_value(5, 1) self.assertEqual(0.0, val) val = sh1.get_numeric_value(6, 1) self.assertEqual(10.0, val) def test_formula_cell_threaded_recalc(self): sh1 = self.doc.append_sheet("Data") sh1.set_numeric_cell(0, 0, 1.1) sh1.set_numeric_cell(1, 0, 1.2) sh1.set_numeric_cell(2, 0, 1.3) sh1.set_formula_cell(0, 1, "SUM(A1:A3)") sh1.set_formula_cell(1, 1, "B1*2") self.doc.calculate(threads=2) # Check the value in B1. v = sh1.get_numeric_value(0, 1) v = round(v, 1) self.assertEqual(v, 3.6) # Check the value in B2. v = sh1.get_numeric_value(1, 1) v = round(v, 1) self.assertEqual(v, 7.2) def test_formula_cell_string(self): sh1 = self.doc.append_sheet("MyData") sh1.set_string_cell(1, 1, "My precious string") # B2 sh1.set_formula_cell(1, 2, "B2") # C2 sh1.set_formula_cell(2, 2, "concatenate(B2, \" is here\")") # C3 self.doc.calculate() self.assertEqual("My precious string", sh1.get_string_value(1, 1)) self.assertEqual("My precious string", sh1.get_string_value(1, 2)) self.assertEqual("My precious string is here", sh1.get_string_value(2, 2)) def test_detached_sheet(self): # You can't set values to a detached sheet that doesn't belong to a # Document object. sh = ixion.Sheet() try: sh.set_numeric_cell(1, 1, 12) self.assertTrue(False, "failed to raise a SheetError.") except ixion.SheetError: pass # expected try: sh.set_string_cell(2, 2, "String") self.assertTrue(False, "failed to raise a SheetError.") except ixion.SheetError: pass # expected try: sh.set_formula_cell(2, 2, "A1") self.assertTrue(False, "failed to raise a SheetError.") except ixion.SheetError: pass # expected try: sh.empty_cell(2, 1) self.assertTrue(False, "failed to raise a SheetError.") except ixion.SheetError: pass # expected try: val = sh.get_numeric_value(2, 1) self.assertTrue(False, "failed to raise a SheetError.") except ixion.SheetError: pass # expected try: s = sh.get_string_value(2, 1) self.assertTrue(False, "failed to raise a SheetError.") except ixion.SheetError: pass # expected try: expr = sh.get_formula_expression(2, 1) self.assertTrue(False, "failed to raise a SheetError.") except ixion.SheetError: pass # expected if __name__ == '__main__': unittest.main()