You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
9.5 KiB
260 lines
9.5 KiB
from unittest import TestCase
|
|
import import_json
|
|
|
|
class TestImportJSON(TestCase):
|
|
|
|
maxDiff = None
|
|
|
|
def test_simple_json_array(self):
|
|
grist_tables = import_json.dumps([{'a': 1, 'b': 'baba'}, {'a': 4, 'b': 'abab'}], '')
|
|
self.assertEqual(grist_tables['tables'], [{
|
|
'column_metadata': [
|
|
{'id': 'a', 'type': 'Int'}, {'id': 'b', 'type': 'Text'}],
|
|
'table_data': [[1, 4], ['baba', 'abab']],
|
|
'table_name': ''
|
|
}])
|
|
|
|
def test_missing_data(self):
|
|
grist_tables = import_json.dumps([{'a': 1}, {'b': 'abab'}, {'a': 4}])
|
|
self.assertEqual(grist_tables['tables'], [{
|
|
'column_metadata': [
|
|
{'id': 'a', 'type': 'Int'}, {'id': 'b', 'type': 'Text'}],
|
|
'table_data': [[1, None, 4], [None, 'abab', None]],
|
|
'table_name': ''
|
|
}])
|
|
|
|
def test_even_more_simple_array(self):
|
|
self.assertEqual(
|
|
import_json.dumps(['apple', 'pear', 'banana'], '')['tables'],
|
|
[{
|
|
'column_metadata': [
|
|
{'id': '', 'type': 'Text'}],
|
|
'table_data': [['apple', 'pear', 'banana']],
|
|
'table_name': ''
|
|
}])
|
|
|
|
def test_mixing_simple_and_even_more_simple(self):
|
|
self.assertEqual(
|
|
import_json.dumps(['apple', 'pear', {'a': 'some cucumbers'}, 'banana'], '')['tables'],
|
|
[{
|
|
'column_metadata': [
|
|
{'id': '', 'type': 'Text'},
|
|
{'id': 'a', 'type': 'Text'}],
|
|
'table_data': [['apple', 'pear', None, 'banana'], [None, None, 'some cucumbers', None]],
|
|
'table_name': ''
|
|
}])
|
|
|
|
def test_array_with_reference(self):
|
|
# todo: reference should follow Grist's format
|
|
self.assertEqual(
|
|
import_json.dumps([{'a': {'b': 2}, 'c': 'foo'}], 'Hello')['tables'],
|
|
[{
|
|
'column_metadata': [
|
|
{'id': 'a', 'type': 'Ref:Hello_a'}, {'id': 'c', 'type': 'Text'}
|
|
],
|
|
'table_data': [[1], ['foo']],
|
|
'table_name': 'Hello'
|
|
}, {
|
|
'column_metadata': [
|
|
{'id': 'b', 'type': 'Int'}
|
|
],
|
|
'table_data': [[2]],
|
|
'table_name': 'Hello_a'
|
|
}])
|
|
|
|
def test_nested_nested_object(self):
|
|
self.assertEqual(
|
|
import_json.dumps([{'a': {'b': 2, 'd': {'a': 'sugar'}}, 'c': 'foo'}], 'Hello')['tables'],
|
|
[{
|
|
'column_metadata': [
|
|
{'id': 'a', 'type': 'Ref:Hello_a'}, {'id': 'c', 'type': 'Text'}
|
|
],
|
|
'table_data': [[1], ['foo']],
|
|
'table_name': 'Hello'
|
|
}, {
|
|
'column_metadata': [
|
|
{'id': 'b', 'type': 'Int'}, {'id': 'd', 'type': 'Ref:Hello_a_d'}
|
|
],
|
|
'table_data': [[2], [1]],
|
|
'table_name': 'Hello_a'
|
|
}, {
|
|
'column_metadata': [
|
|
{'id': 'a', 'type': 'Text'}
|
|
],
|
|
'table_data': [['sugar']],
|
|
'table_name': 'Hello_a_d'
|
|
}])
|
|
|
|
|
|
def test_array_with_list(self):
|
|
self.assertEqual(
|
|
import_json.dumps([{'a': ['ES', 'FR', 'US']}, {'a': ['FR']}], 'Hello')['tables'],
|
|
[{
|
|
'column_metadata': [],
|
|
'table_data': [],
|
|
'table_name': 'Hello'
|
|
}, {
|
|
'column_metadata': [{'id': '', 'type': 'Text'}, {'id': 'Hello', 'type': 'Ref:Hello'}],
|
|
'table_data': [['ES', 'FR', 'US', 'FR'], [1, 1, 1, 2]],
|
|
'table_name': 'Hello_a'
|
|
}])
|
|
|
|
def test_array_with_list_of_dict(self):
|
|
self.assertEqual(
|
|
import_json.dumps([{'a': [{'b': 1}, {'b': 4}]}, {'c': 2}], 'Hello')['tables'],
|
|
[ {
|
|
'column_metadata': [{'id': 'c', 'type': 'Int'}],
|
|
'table_data': [[None, 2]],
|
|
'table_name': 'Hello'
|
|
}, {
|
|
'column_metadata': [
|
|
{'id': 'b', 'type': 'Int'},
|
|
{'id': 'Hello', 'type': 'Ref:Hello'}
|
|
],
|
|
'table_data': [[1, 4], [1, 1]],
|
|
'table_name': 'Hello_a'
|
|
}])
|
|
|
|
|
|
def test_array_of_array(self):
|
|
self.assertEqual(
|
|
import_json.dumps([['FR', 'US'], ['ES', 'CH']], 'Hello')['tables'],
|
|
[{
|
|
'column_metadata': [],
|
|
'table_data': [],
|
|
'table_name': 'Hello'
|
|
}, {
|
|
'column_metadata': [{'id': '', 'type': 'Text'}, {'id': 'Hello', 'type': 'Ref:Hello'}],
|
|
'table_data': [['FR', 'US', 'ES', 'CH'], [1, 1, 2, 2]],
|
|
'table_name': 'Hello_'
|
|
}, ])
|
|
|
|
|
|
def test_json_dict(self):
|
|
self.assertEqual(
|
|
import_json.dumps({
|
|
'foo': [{'a': 1, 'b': 'santa'}, {'a': 4, 'b': 'cats'}],
|
|
'bar': [{'c': 2, 'd': 'ducks'}, {'c': 5, 'd': 'dogs'}],
|
|
'status': {'success': True, 'time': '5s'}
|
|
}, 'Hello')['tables'], [{
|
|
'table_name': 'Hello',
|
|
'column_metadata': [{'id': 'status', 'type': 'Ref:Hello_status'}],
|
|
'table_data': [[1]]
|
|
}, {
|
|
'table_name': 'Hello_bar',
|
|
'column_metadata': [
|
|
{'id': 'c', 'type': 'Int'},
|
|
{'id': 'd', 'type': 'Text'},
|
|
{'id': 'Hello', 'type': 'Ref:Hello'}
|
|
],
|
|
'table_data': [[2, 5], ['ducks', 'dogs'], [1, 1]]
|
|
}, {
|
|
'table_name': 'Hello_foo',
|
|
'column_metadata': [
|
|
{'id': 'a', 'type': 'Int'},
|
|
{'id': 'b', 'type': 'Text'},
|
|
{'id': 'Hello', 'type': 'Ref:Hello'}],
|
|
'table_data': [[1, 4], ['santa', 'cats'], [1, 1]]
|
|
}, {
|
|
'table_name': 'Hello_status',
|
|
'column_metadata': [
|
|
{'id': 'success', 'type': 'Bool'},
|
|
{'id': 'time', 'type': 'Text'}
|
|
],
|
|
'table_data': [[True], ['5s']]
|
|
}])
|
|
|
|
def test_json_types(self):
|
|
self.assertEqual(import_json.dumps({
|
|
'a': 3, 'b': 3.14, 'c': True, 'd': 'name', 'e': -4, 'f': '3.14', 'g': None
|
|
}, 'Hello')['tables'],
|
|
[{
|
|
'table_name': 'Hello',
|
|
'column_metadata': [
|
|
{'id': 'a', 'type': 'Int'},
|
|
{'id': 'b', 'type': 'Numeric'},
|
|
{'id': 'c', 'type': 'Bool'},
|
|
{'id': 'd', 'type': 'Text'},
|
|
{'id': 'e', 'type': 'Int'},
|
|
{'id': 'f', 'type': 'Text'},
|
|
{'id': 'g', 'type': 'Text'}
|
|
],
|
|
'table_data': [[3], [3.14], [True], ['name'], [-4], ['3.14'], [None]]
|
|
}])
|
|
|
|
def test_type_is_defined_with_first_value(self):
|
|
tables = import_json.dumps([{'a': 'some text'}, {'a': 3}], '')
|
|
self.assertIsNotNone(tables['tables'])
|
|
self.assertIsNotNone(tables['tables'][0])
|
|
self.assertIsNotNone(tables['tables'][0]['column_metadata'])
|
|
self.assertIsNotNone(tables['tables'][0]['column_metadata'][0])
|
|
self.assertEqual(tables['tables'][0]['column_metadata'][0]['type'], 'Text')
|
|
|
|
def test_first_unique_key(self):
|
|
self.assertEqual(import_json.first_available_key({'a': 1}, 'a'), 'a2')
|
|
self.assertEqual(import_json.first_available_key({'a': 1}, 'b'), 'b')
|
|
self.assertEqual(import_json.first_available_key({'a': 1, 'a2': 1}, 'a'), 'a3')
|
|
|
|
|
|
def dump_tables(options):
|
|
data = {
|
|
"foos": [
|
|
{'foo': 1, 'link': [1, 2]},
|
|
{'foo': 2, 'link': [1, 2]}
|
|
],
|
|
"bar": {'hi': 'santa'}
|
|
}
|
|
return [t for t in import_json.dumps(data, 'FooBar', options)['tables']]
|
|
|
|
|
|
class TestParseOptions(TestCase):
|
|
|
|
maxDiff = None
|
|
|
|
# helpers
|
|
def assertColInTable(self, tables, **kwargs):
|
|
table = next(t for t in tables if t['table_name'] == kwargs['table_name'])
|
|
self.assertEqual(any(col['id'] == kwargs['col_id'] for col in table['column_metadata']),
|
|
kwargs['present'])
|
|
|
|
def assertTableNamesEqual(self, tables, expected_table_names):
|
|
table_names = [t['table_name'] for t in tables]
|
|
self.assertEqual(sorted(table_names), sorted(expected_table_names))
|
|
|
|
def test_including_empty_string_includes_all(self):
|
|
tables = dump_tables({'includes': '', 'excludes': ''})
|
|
self.assertTableNamesEqual(tables, ['FooBar', 'FooBar_bar', 'FooBar_foos', 'FooBar_foos_link'])
|
|
|
|
def test_including_foos_includes_nested_object_and_removes_ref_to_table_not_included(self):
|
|
tables = dump_tables({'includes': 'FooBar_foos', 'excludes': ''})
|
|
self.assertTableNamesEqual(tables, ['FooBar_foos', 'FooBar_foos_link'])
|
|
self.assertColInTable(tables, table_name='FooBar_foos', col_id='FooBar', present=False)
|
|
tables = dump_tables({'includes': 'FooBar_foos_link', 'excludes': ''})
|
|
self.assertTableNamesEqual(tables, ['FooBar_foos_link'])
|
|
self.assertColInTable(tables, table_name='FooBar_foos_link', col_id='FooBar_foos',
|
|
present=False)
|
|
|
|
def test_excluding_foos_excludes_nested_object_and_removes_link_to_excluded_table(self):
|
|
tables = dump_tables({'includes': '', 'excludes': 'FooBar_foos'})
|
|
self.assertTableNamesEqual(tables, ['FooBar', 'FooBar_bar'])
|
|
self.assertColInTable(tables, table_name='FooBar', col_id='foos', present=False)
|
|
|
|
def test_excludes_works_on_nested_object_that_are_included(self):
|
|
tables = dump_tables({'includes': 'FooBar_foos', 'excludes': 'FooBar_foos_link'})
|
|
self.assertTableNamesEqual(tables, ['FooBar_foos'])
|
|
|
|
def test_excludes_works_on_property(self):
|
|
tables = dump_tables({'includes': '', 'excludes': 'FooBar_foos_foo'})
|
|
self.assertTableNamesEqual(tables, ['FooBar', 'FooBar_foos', 'FooBar_foos_link', 'FooBar_bar'])
|
|
self.assertColInTable(tables, table_name='FooBar_foos', col_id='foo', present=False)
|
|
|
|
def test_works_with_multiple_includes(self):
|
|
tables = dump_tables({'includes': 'FooBar_foos_link', 'excludes': ''})
|
|
self.assertTableNamesEqual(tables, ['FooBar_foos_link'])
|
|
tables = dump_tables({'includes': 'FooBar_foos_link;FooBar_bar', 'excludes': ''})
|
|
self.assertTableNamesEqual(tables, ['FooBar_bar', 'FooBar_foos_link'])
|
|
|
|
def test_works_with_multiple_excludes(self):
|
|
tables = dump_tables({'includes': '', 'excludes': 'FooBar_foos_link;FooBar_bar'})
|
|
self.assertTableNamesEqual(tables, ['FooBar', 'FooBar_foos'])
|