diff options
| author | Xavier Morel <xmo@odoo.com> | 2018-08-07 16:34:11 +0200 |
|---|---|---|
| committer | Xavier Morel <xmo@odoo.com> | 2018-08-07 16:46:29 +0200 |
| commit | 36ee8a78ece08c3fd18ec2cd4904e464641e0b5d (patch) | |
| tree | 4a424086b7e7360a155a9b62008f1e76f34642d2 /addons/base_import/tests/test_csv_magic.py | |
| parent | 5f92f853e2c565ba299c452b97e0376d0c2705ef (diff) | |
[IMP] base_import: attempt to automatically guess the separator
It would probably be even better to iterate the file content and get
the non-quoted non-alphanumeric characters as separator
candidates (instead of a hard-coded list) however Python does not seem
to have a decoding iterator (taking bytes and yielding an iterator of
codepoints or even grapheme clusters) — incidentally uniseg seems to
require up-front decoding as well — so that's not really convenient as
we may be dealing with large-ish files and not want to load it
entirely in memory.
An alternative would be to use TextIOWrapper and iterate the file by
buffers of a few ks, and classify that based on either codepoints or
grapheme clusters.
Diffstat (limited to 'addons/base_import/tests/test_csv_magic.py')
| -rw-r--r-- | addons/base_import/tests/test_csv_magic.py | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/addons/base_import/tests/test_csv_magic.py b/addons/base_import/tests/test_csv_magic.py index 2b088c37afe..92724ec360b 100644 --- a/addons/base_import/tests/test_csv_magic.py +++ b/addons/base_import/tests/test_csv_magic.py @@ -6,7 +6,17 @@ import codecs from odoo.tests import common -class TestEncoding(common.TransactionCase): +class ImportCase(common.TransactionCase): + def _make_import(self, contents): + return self.env['base_import.import'].create({ + 'res_model': 'base_import.tests.models.complex', + 'file_name': 'f', + 'file_type': 'text/csv', + 'file': contents, + }) + + +class TestEncoding(ImportCase): """ create + parse_preview -> check result options """ @@ -47,13 +57,83 @@ class TestEncoding(common.TransactionCase): self.assertEqual(r['options']['encoding'], 'iso-8859-1') self.assertEqual(r['preview'], [['text'], [s.decode('iso-8859-1')]]) - def _make_import(self, contents): - return self.env['base_import.import'].create({ - 'res_model': 'base_import.tests.models.complex', - 'file_name': 'f', - 'file_type': 'text/csv', - 'file': contents, +class TestFileSeparator(ImportCase): + + def setUp(self): + super().setUp() + self.imp = self._make_import( +"""c|f +a|1 +b|2 +c|3 +d|4 +""") + + def test_explicit_success(self): + r = self.imp.parse_preview({ + 'separator': '|', + 'headers': True, + 'quoting': '"', + }) + self.assertEqual(r['headers'], ['c', 'f']) + self.assertEqual(r['preview'], [ + ['a', '1'], + ['b', '2'], + ['c', '3'], + ['d', '4'], + ]) + self.assertEqual(r['options']['separator'], '|') + + def test_explicit_fail(self): + """ Don't protect user against making mistakes + """ + r = self.imp.parse_preview({ + 'separator': ',', + 'headers': True, + 'quoting': '"', + }) + self.assertEqual(r['headers'], ['c|f']) + self.assertEqual(r['preview'], [ + ['a|1'], + ['b|2'], + ['c|3'], + ['d|4'], + ]) + self.assertEqual(r['options']['separator'], ',') + + def test_guess_ok(self): + r = self.imp.parse_preview({ + 'separator': '', + 'headers': True, + 'quoting': '"', + }) + self.assertEqual(r['headers'], ['c', 'f']) + self.assertEqual(r['preview'], [ + ['a', '1'], + ['b', '2'], + ['c', '3'], + ['d', '4'], + ]) + self.assertEqual(r['options']['separator'], '|') + + def test_noguess(self): + """ If the guesser has no idea what the separator is, it defaults to + "," but should not set that value + """ + imp = self._make_import('c\na\nb\nc\nd') + r = imp.parse_preview({ + 'separator': '', + 'headers': True, + 'quoting': '"', }) + self.assertEqual(r['headers'], ['c']) + self.assertEqual(r['preview'], [ + ['a'], + ['b'], + ['c'], + ['d'], + ]) + self.assertEqual(r['options']['separator'], '') class TestNumberSeparators(common.TransactionCase): def test_parse_float(self): |
