From 8e98db48c409c732c9579049f506ccbd4461651f Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 18 Feb 2017 23:47:52 +0800 Subject: [PATCH] Added test cases. --- ods2md.py | 18 +++++++++--------- test.py | 18 ++++++++++++++++++ test/padded.md | 8 ++++++++ test/padded.ods | Bin 0 -> 8035 bytes test/sample.md | 12 ++++++++++++ test/sample.ods | Bin 0 -> 16606 bytes 6 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 test.py create mode 100644 test/padded.md create mode 100644 test/padded.ods create mode 100644 test/sample.md create mode 100644 test/sample.ods diff --git a/ods2md.py b/ods2md.py index b7dc83f..18dd95f 100755 --- a/ods2md.py +++ b/ods2md.py @@ -45,7 +45,7 @@ def display_text(cell): def display_len(s): return sum(DISPLAY_WIDTH[unicodedata.east_asian_width(c)] for c in s) -def main(odf_path): +def main(odf_path, out_file): ods = ezodf.opendoc(odf_path) for sheet in ods.sheets: @@ -53,7 +53,7 @@ def main(odf_path): if not any(column_widths): continue - print('##', sheet.name) + print('##', sheet.name, file=out_file) printed_header = False for row in sheet.rows(): @@ -61,22 +61,22 @@ def main(odf_path): if not any(contents): continue - print('|', end='') + print('|', end='', file=out_file) for m, content in enumerate(contents): column_width = column_widths[m] if not column_width: continue disp_len = column_width + len(content) - display_len(content) - print(' {0:<{1}}'.format(content, disp_len), end=' |') - print() + print(' {0:<{1}}'.format(content, disp_len), end=' |', file=out_file) + print(file=out_file) if not printed_header: printed_header = True - print('|', end='') + print('|', end='', file=out_file) for w in column_widths: if w: - print(':', '-' * (w+1), '|', sep='', end='') - print() + print(':', '-' * (w+1), '|', sep='', end='', file=out_file) + print(file=out_file) if __name__ == '__main__': - main(sys.argv[1]) + main(sys.argv[1], sys.stdout) diff --git a/test.py b/test.py new file mode 100644 index 0000000..64c96dd --- /dev/null +++ b/test.py @@ -0,0 +1,18 @@ +import ods2md + +import unittest +import os.path +import io + +class Test(unittest.TestCase): + def perform_test(self, base): + output = io.StringIO() + ods2md.main(os.path.join('test', base + '.ods'), output) + with open(os.path.join('test', base + '.md'), 'r') as f: + self.assertMultiLineEqual(f.read(), output.getvalue()) + + def test_sample(self): + self.perform_test('sample') + + def test_padded(self): + self.perform_test('padded') diff --git a/test/padded.md b/test/padded.md new file mode 100644 index 0000000..30c1a26 --- /dev/null +++ b/test/padded.md @@ -0,0 +1,8 @@ +## Sheet1 +| X | Y | +|:----|:-----------| +| 0.1 | 1999-12-31 | +| 0.2 | 2000-01-01 | +| | ! | +| 0.4 | | +| 0.7 | ? | diff --git a/test/padded.ods b/test/padded.ods new file mode 100644 index 0000000000000000000000000000000000000000..d7e5c8f99d4405ced77b2ebd646b87fbc4126963 GIT binary patch literal 8035 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 Lq6zKgzYP3ecf(oq literal 0 HcmV?d00001 diff --git a/test/sample.md b/test/sample.md new file mode 100644 index 0000000..eea0fd9 --- /dev/null +++ b/test/sample.md @@ -0,0 +1,12 @@ +## Sheet1 +| 版本 | 英文代號 | 中譯 | +|:-------------|:-----------------|:-------------------| +| Ubuntu 17.04 | Zesty Zapus | 熱情的北美草原跳鼠 | +| Ubuntu 16.10 | Yakkety Yak | 喋喋不休的氂牛 | +| Ubuntu 16.04 | Xenial Xerus | 好客的非洲地松鼠 | +| Ubuntu 15.10 | Wily Werewolf | 老謀深算的狼人 | +| Ubuntu 15.04 | Vivid Vervet | 活潑的長尾黑顎猴 | +| Ubuntu 14.10 | Utopic Unicorn | 烏托邦的獨角獸 | +| Ubuntu 14.04 | Trusty Tahr | 可靠的塔爾羊 | +| Ubuntu 13.10 | Saucy Salamander | 活潑的蠑螈 | +| Ubuntu 13.04 | Raring Ringtail | 卯足了勁的環尾貓熊 | diff --git a/test/sample.ods b/test/sample.ods new file mode 100644 index 0000000000000000000000000000000000000000..ee4dcd0463ad09d90ff3712f0144aa38057c854a GIT binary patch literal 16606 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 UUrrhb2=Uj)1oT&3czz%Ke>1RKfdBvi literal 0 HcmV?d00001