Skip to content

Commit

Permalink
Allow nested records w/ null values. (#7297)
Browse files Browse the repository at this point in the history
Adds explicit unit tests for helpers added in #7022.

Closes #7294.
  • Loading branch information
tseaver authored Feb 7, 2019
1 parent ade4dd5 commit dc3f531
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 1 deletion.
5 changes: 4 additions & 1 deletion bigquery/google/cloud/bigquery/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,10 @@ def _record_field_to_json(fields, row_value):

for subindex, subfield in enumerate(fields):
subname = subfield.name
subvalue = row_value[subname] if isdict else row_value[subindex]
if isdict:
subvalue = row_value.get(subname)
else:
subvalue = row_value[subindex]
record[subname] = _field_to_json(subfield, subvalue)
return record

Expand Down
121 changes: 121 additions & 0 deletions bigquery/tests/unit/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,127 @@ def test_w_datetime(self):
self.assertEqual(self._call_fut(when), "12:13:41")


def _make_field(field_type, mode="NULLABLE", name="testing", fields=()):
from google.cloud.bigquery.schema import SchemaField

return SchemaField(name=name, field_type=field_type, mode=mode, fields=fields)


class Test_scalar_field_to_json(unittest.TestCase):
def _call_fut(self, field, value):
from google.cloud.bigquery._helpers import _scalar_field_to_json

return _scalar_field_to_json(field, value)

def test_w_unknown_field_type(self):
field = _make_field("UNKNOWN")
original = object()
converted = self._call_fut(field, original)
self.assertIs(converted, original)

def test_w_known_field_type(self):
field = _make_field("INT64")
original = 42
converted = self._call_fut(field, original)
self.assertEqual(converted, str(original))


class Test_repeated_field_to_json(unittest.TestCase):
def _call_fut(self, field, value):
from google.cloud.bigquery._helpers import _repeated_field_to_json

return _repeated_field_to_json(field, value)

def test_w_empty(self):
field = _make_field("INT64", mode="REPEATED")
original = []
converted = self._call_fut(field, original)
self.assertEqual(converted, original)
self.assertEqual(field.mode, "REPEATED")

def test_w_non_empty(self):
field = _make_field("INT64", mode="REPEATED")
original = [42]
converted = self._call_fut(field, original)
self.assertEqual(converted, [str(value) for value in original])
self.assertEqual(field.mode, "REPEATED")


class Test_record_field_to_json(unittest.TestCase):
def _call_fut(self, field, value):
from google.cloud.bigquery._helpers import _record_field_to_json

return _record_field_to_json(field, value)

def test_w_empty(self):
fields = []
original = []
converted = self._call_fut(fields, original)
self.assertEqual(converted, {})

def test_w_non_empty_list(self):
fields = [
_make_field("INT64", name="one", mode="NULLABLE"),
_make_field("STRING", name="two", mode="NULLABLE"),
]
original = [42, "two"]
converted = self._call_fut(fields, original)
self.assertEqual(converted, {"one": "42", "two": "two"})

def test_w_non_empty_dict(self):
fields = [
_make_field("INT64", name="one", mode="NULLABLE"),
_make_field("STRING", name="two", mode="NULLABLE"),
]
original = {"one": 42, "two": "two"}
converted = self._call_fut(fields, original)
self.assertEqual(converted, {"one": "42", "two": "two"})

def test_w_missing_nullable(self):
fields = [
_make_field("INT64", name="one", mode="NULLABLE"),
_make_field("STRING", name="two", mode="NULLABLE"),
]
original = {"one": 42}
converted = self._call_fut(fields, original)
self.assertEqual(converted, {"one": "42", "two": None})


class Test_field_to_json(unittest.TestCase):
def _call_fut(self, field, value):
from google.cloud.bigquery._helpers import _field_to_json

return _field_to_json(field, value)

def test_w_none(self):
field = _make_field("INT64")
original = None
converted = self._call_fut(field, original)
self.assertIsNone(converted)

def test_w_repeated(self):
field = _make_field("INT64", mode="REPEATED")
original = [42, 17]
converted = self._call_fut(field, original)
self.assertEqual(converted, [str(value) for value in original])

def test_w_record(self):
subfields = [
_make_field("INT64", name="one"),
_make_field("STRING", name="two"),
]
field = _make_field("RECORD", fields=subfields)
original = {"one": 42, "two": "two"}
converted = self._call_fut(field, original)
self.assertEqual(converted, {"one": "42", "two": "two"})

def test_w_scalar(self):
field = _make_field("INT64")
original = 42
converted = self._call_fut(field, original)
self.assertEqual(converted, str(original))


class Test_snake_to_camel_case(unittest.TestCase):
def _call_fut(self, value):
from google.cloud.bigquery._helpers import _snake_to_camel_case
Expand Down

0 comments on commit dc3f531

Please sign in to comment.