From 435b82faaf8f8a90577d557f8877b95a8ceb28d6 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 24 May 2018 03:47:21 +0900 Subject: [PATCH] Optional params must be omittable [changelog skip] --- src/Nirum/Targets/Python.hs | 9 +++++++++ test/nirum_fixture/fixture/foo.nrm | 1 + test/python/service_test.py | 22 ++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/Nirum/Targets/Python.hs b/src/Nirum/Targets/Python.hs index 6a60006..2d97a24 100644 --- a/src/Nirum/Targets/Python.hs +++ b/src/Nirum/Targets/Python.hs @@ -370,6 +370,11 @@ mpcBehindName :: MethodParameterCode -> T.Text mpcBehindName MethodParameterCode { mpcParam = Parameter pName _ _ } = toBehindSnakeCaseText pName +mpcOptional :: MethodParameterCode -> Bool +mpcOptional mpc = case mpcType mpc of + OptionModifier _ -> True + _ -> False + mpcType :: MethodParameterCode -> TypeExpression mpcType MethodParameterCode { mpcParam = Parameter _ typeExpr _ } = typeExpr @@ -1313,7 +1318,11 @@ class #{className}(service_type): try: field_value = value['#{mpcBehindName mpc}'] except KeyError: +%{ if mpcOptional mpc } + result['#{mpcAttributeName mpc}'] = None +%{ else } on_error('.#{mpcBehindName mpc}', 'Expected to exist.') +%{ endif } else: result['#{mpcAttributeName mpc}'] = \ table['#{mpcBehindName mpc}']( diff --git a/test/nirum_fixture/fixture/foo.nrm b/test/nirum_fixture/fixture/foo.nrm index 5f65cbf..645fed5 100644 --- a/test/nirum_fixture/fixture/foo.nrm +++ b/test/nirum_fixture/fixture/foo.nrm @@ -125,6 +125,7 @@ union animal = cat service sample-service ( sample-method (animal a, product b/bb, gender c, way d/dd, uuid e, binary f/ff, bigint g, text h/hh), + sample-method-with-optional-param(uuid a, animal? b), animal sample-method-that-returns(), ); diff --git a/test/python/service_test.py b/test/python/service_test.py index e42be95..08d2345 100644 --- a/test/python/service_test.py +++ b/test/python/service_test.py @@ -144,6 +144,28 @@ def test_service_deserialize_arguments(fx_method_args): assert errors == {('', 'Expected an object.')} +def test_service_deserialize_arguments_with_omitted_keys(fx_dog): + m = SampleService.sample_method_with_optional_param + f = m.__nirum_deserialize_arguments__ + payload = { + 'a': 'f7db93e3-731e-48ef-80a2-cac81e02f1ae', + 'b': fx_dog[1], + } + expected = { + 'a': uuid.UUID('F7DB93E3-731E-48EF-80A2-CAC81E02F1AE'), + 'b': fx_dog[0], + } + assert f(payload) == expected + assert f(dict(payload, b=None)) == dict(expected, b=None) + assert f({'a': payload['a']}) == dict(expected, b=None) + with raises(ValueError) as e: + f({'b': fx_dog[1]}) + assert str(e.value) == '.a: Expected to exist.' + with raises(ValueError) as e: + f(dict(payload, b=dict(fx_dog[1], name=None))) + assert str(e.value) == '.b.name: Expected a string.' + + def test_service_argument_serializers(fx_method_args): args, expected = fx_method_args table = SampleService.sample_method.__nirum_argument_serializers__