Repository: incubator-airflow Updated Branches: refs/heads/master 917adbdba -> 502410b0d
[AIRFLOW-1233] Cover utils.json with unit tests Closes #2316 from skudriashev/airflow-1233 Project: http://git-wip-us.apache.org/repos/asf/incubator-airflow/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-airflow/commit/502410b0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-airflow/tree/502410b0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-airflow/diff/502410b0 Branch: refs/heads/master Commit: 502410b0d9719bd1183f972b66a50452a004f249 Parents: 917adbd Author: Stanislav Kudriashev <[email protected]> Authored: Sun May 21 20:20:23 2017 +0200 Committer: Bolke de Bruin <[email protected]> Committed: Sun May 21 20:20:23 2017 +0200 ---------------------------------------------------------------------- airflow/utils/json.py | 17 ++++----- tests/utils/test_json.py | 82 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/502410b0/airflow/utils/json.py ---------------------------------------------------------------------- diff --git a/airflow/utils/json.py b/airflow/utils/json.py index b940335..5984ac6 100644 --- a/airflow/utils/json.py +++ b/airflow/utils/json.py @@ -22,11 +22,11 @@ import json import numpy as np -# Dates and JSON encoding/deconding +# Dates and JSON encoding/decoding def json_ser(obj): - """ - json serializer that deals with dates + """json serializer that deals with dates. + usage: json.dumps(object, default=utils.json.json_ser) """ if isinstance(obj, (datetime, date)): @@ -34,20 +34,21 @@ def json_ser(obj): class AirflowJsonEncoder(json.JSONEncoder): + def default(self, obj): # convert dates and numpy objects in a json serializable format if isinstance(obj, datetime): return obj.strftime('%Y-%m-%dT%H:%M:%SZ') elif isinstance(obj, date): return obj.strftime('%Y-%m-%d') - elif type(obj) in [np.int_, np.intc, np.intp, np.int8, np.int16, + elif type(obj) in (np.int_, np.intc, np.intp, np.int8, np.int16, np.int32, np.int64, np.uint8, np.uint16, - np.uint32, np.uint64]: + np.uint32, np.uint64): return int(obj) - elif type(obj) in [np.bool_]: + elif type(obj) in (np.bool_,): return bool(obj) - elif type(obj) in [np.float_, np.float16, np.float32, np.float64, - np.complex_, np.complex64, np.complex128]: + elif type(obj) in (np.float_, np.float16, np.float32, np.float64, + np.complex_, np.complex64, np.complex128): return float(obj) # Let the base class default method raise the TypeError http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/502410b0/tests/utils/test_json.py ---------------------------------------------------------------------- diff --git a/tests/utils/test_json.py b/tests/utils/test_json.py new file mode 100644 index 0000000..160f923 --- /dev/null +++ b/tests/utils/test_json.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from datetime import datetime, date +import json +import unittest + +import numpy as np + +from airflow.utils import json as utils_json + + +class TestJsonSer(unittest.TestCase): + + def test_json_ser_datetime(self): + obj = datetime.strptime('2017-05-21 00:00:00', '%Y-%m-%d %H:%M:%S') + self.assertEqual( + json.dumps(obj, default=utils_json.json_ser), + '"2017-05-21T00:00:00"', + ) + + def test_json_ser_date(self): + self.assertEqual( + json.dumps(date(2017, 5, 21), default=utils_json.json_ser), + '"2017-05-21"', + ) + + +class TestAirflowJsonEncoder(unittest.TestCase): + + def test_encode_datetime(self): + obj = datetime.strptime('2017-05-21 00:00:00', '%Y-%m-%d %H:%M:%S') + self.assertEqual( + json.dumps(obj, cls=utils_json.AirflowJsonEncoder), + '"2017-05-21T00:00:00Z"' + ) + + def test_encode_date(self): + self.assertEqual( + json.dumps(date(2017, 5, 21), cls=utils_json.AirflowJsonEncoder), + '"2017-05-21"' + ) + + def test_encode_numpy_int(self): + self.assertEqual( + json.dumps(np.int32(5), cls=utils_json.AirflowJsonEncoder), + '5' + ) + + def test_encode_numpy_bool(self): + self.assertEqual( + json.dumps(np.bool_(True), cls=utils_json.AirflowJsonEncoder), + 'true' + ) + + def test_encode_numpy_float(self): + self.assertEqual( + json.dumps(np.float16(3.76953125), cls=utils_json.AirflowJsonEncoder), + '3.76953125' + ) + + def test_encode_raises(self): + self.assertRaisesRegexp(TypeError, + "^%s is not JSON serializable$" % Exception, + json.dumps, + Exception, + cls=utils_json.AirflowJsonEncoder) + + +if __name__ == '__main__': + unittest.main()
