diff --git a/fauna/encoding/encoder.py b/fauna/encoding/encoder.py index b3c8946e..8c9c916c 100644 --- a/fauna/encoding/encoder.py +++ b/fauna/encoding/encoder.py @@ -165,10 +165,15 @@ def _encode(o: Any, _markers: Optional[Set] = None): elif isinstance(o, date): return {"value": FaunaEncoder.from_date(o)} elif isinstance(o, Document): - return {"value": FaunaEncoder.from_doc_ref(DocumentReference(o.coll, o.id))} + return { + "value": FaunaEncoder.from_doc_ref(DocumentReference(o.coll, o.id)) + } elif isinstance(o, NamedDocument): - return {"value": FaunaEncoder.from_named_doc_ref( - NamedDocumentReference(o.coll, o.name))} + return { + "value": + FaunaEncoder.from_named_doc_ref( + NamedDocumentReference(o.coll, o.name)) + } elif isinstance(o, NullDocument): return FaunaEncoder.encode(o.ref) elif isinstance(o, (list, tuple)): @@ -196,4 +201,8 @@ def _encode_dict(dct, markers): raise ValueError("Circular reference detected") markers.add(id(dct)) - return {"object": {k: FaunaEncoder._encode(v, markers) for k, v in dct.items()}} + return { + "object": { + k: FaunaEncoder._encode(v, markers) for k, v in dct.items() + } + } diff --git a/tests/integration/test_composition.py b/tests/integration/test_composition.py index f8e70408..49e0b0c9 100644 --- a/tests/integration/test_composition.py +++ b/tests/integration/test_composition.py @@ -48,14 +48,37 @@ def update_doc_by_email(email: str, data: dict): def test_array_composition(client): - queries = [fql("1"), fql("2"), {"key": 3}, [fql("${inner}", inner={"inner": "thing"})]] + queries = [ + fql("1"), + fql("2"), { + "key": 3 + }, [fql("${inner}", inner={"inner": "thing"})] + ] q = fql("${queries}", queries=queries) res = client.query(q).data assert [1, 2, {'key': 3}, [{'inner': 'thing'}]] == res def test_object_composition(client): - queries = {1: fql("1"), 2: fql("2"), 3: {"key": fql("3")}, 4: {"inner": fql("${inner}", inner=["inner", "thing"])}} + queries = { + 1: fql("1"), + 2: fql("2"), + 3: { + "key": fql("3") + }, + 4: { + "inner": fql("${inner}", inner=["inner", "thing"]) + } + } q = fql("${queries}", queries=queries) res = client.query(q).data - assert {'1': 1, '2': 2, '3': {'key': 3}, '4': {'inner': ['inner', 'thing']}} == res + assert { + '1': 1, + '2': 2, + '3': { + 'key': 3 + }, + '4': { + 'inner': ['inner', 'thing'] + } + } == res diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 3c9e28d3..5849d519 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -147,12 +147,15 @@ def complex_typed_object(): }] } + @pytest.fixture def complex_wire_encoded_object(): return { 'object': { 'bugs_coll': { - 'value': {'@mod': 'Bugs'} + 'value': { + '@mod': 'Bugs' + } }, 'bug': { 'value': { @@ -164,22 +167,33 @@ def complex_wire_encoded_object(): } } }, - 'name': - {'value': 'fir'}, + 'name': { + 'value': 'fir' + }, 'age': { - 'value': {'@int': '200'} + 'value': { + '@int': '200' + } }, 'birthdate': { - 'value': {'@date': '1823-02-08'} + 'value': { + '@date': '1823-02-08' + } }, 'molecules': { - 'value': {'@long': '999999999999999999'} + 'value': { + '@long': '999999999999999999' + } }, 'circumference': { - 'value': {'@double': '3.82'} + 'value': { + '@double': '3.82' + } }, 'created_at': { - 'value': {'@time': '2003-02-08T13:28:12.000555+00:00'} + 'value': { + '@time': '2003-02-08T13:28:12.000555+00:00' + } }, 'extras': { 'object': { @@ -189,46 +203,60 @@ def complex_wire_encoded_object(): 'object': { 'egg': { 'object': { - 'fertilized': {'value': False} + 'fertilized': { + 'value': False + } } } } }, 'num_sticks': { - 'value': {'@int': '58'} + 'value': { + '@int': '58' + } }, } } } - }, 'measurements': { 'array': [{ 'object': { 'id': { - 'value': {'@int': '1'} + 'value': { + '@int': '1' + } }, 'employee': { - 'value': {'@int': '3'} + 'value': { + '@int': '3' + } }, 'time': { - 'value': {'@time': '2013-02-08T12:00:05.000123+00:00'} + 'value': { + '@time': '2013-02-08T12:00:05.000123+00:00' + } } } }, { - 'object': { - 'id': { - 'value': {'@int': '2'} - }, - 'employee': { - 'value': {'@int': '5'} - }, - 'time': { - 'value': {'@time': '2023-02-08T14:22:01.000001+00:00'} - } - } + 'object': { + 'id': { + 'value': { + '@int': '2' + } + }, + 'employee': { + 'value': { + '@int': '5' + } + }, + 'time': { + 'value': { + '@time': '2023-02-08T14:22:01.000001+00:00' + } + } + } }] } - } } diff --git a/tests/unit/test_encoding.py b/tests/unit/test_encoding.py index 9278e8bb..d6400a1c 100644 --- a/tests/unit/test_encoding.py +++ b/tests/unit/test_encoding.py @@ -143,7 +143,16 @@ def test_encode_document_references(subtests): doc_ref = DocumentReference.from_string("Col:123") with subtests.test(msg="encode/decode with @doc"): encoded = FaunaEncoder.encode(doc_ref) - assert {'value': {'@ref': {'coll': {'@mod': 'Col'}, 'id': "123"}}} == encoded + assert { + 'value': { + '@ref': { + 'coll': { + '@mod': 'Col' + }, + 'id': "123" + } + } + } == encoded decoded = FaunaDecoder.decode(encoded['value']) assert doc_ref == decoded @@ -178,7 +187,16 @@ def test_null_docments(subtests): with subtests.test(msg="encode named null doc"): null_doc = NullDocument( NamedDocumentReference("Collection", "Party"), "not found") - expected = {"value": {"@ref": {"name": "Party", "coll": {"@mod": "Collection"}}}} + expected = { + "value": { + "@ref": { + "name": "Party", + "coll": { + "@mod": "Collection" + } + } + } + } encoded = FaunaEncoder.encode(null_doc) assert expected == encoded @@ -203,7 +221,16 @@ def test_encode_named_document_references(subtests): doc_ref = NamedDocumentReference("Col", "Hi") with subtests.test(msg="encode/decode with @doc"): encoded = FaunaEncoder.encode(doc_ref) - assert {"value": {"@ref": {"name": "Hi", "coll": {"@mod": "Col"}}}} == encoded + assert { + "value": { + "@ref": { + "name": "Hi", + "coll": { + "@mod": "Col" + } + } + } + } == encoded decoded = FaunaDecoder.decode(encoded["value"]) assert doc_ref == decoded @@ -219,7 +246,16 @@ def test_encode_documents(subtests): id="123", coll="Dogs", ts=fixed_datetime, data={"name": "Scout"}) encoded = FaunaEncoder.encode(test) # should encode to a ref! - assert {"value": {"@ref": {"id": "123", "coll": {"@mod": "Dogs"}}}} == encoded + assert { + "value": { + "@ref": { + "id": "123", + "coll": { + "@mod": "Dogs" + } + } + } + } == encoded decoded = FaunaDecoder.decode(encoded["value"]) # refs will decode into references, not Documents assert DocumentReference("Dogs", "123") == decoded @@ -248,7 +284,16 @@ def test_encode_named_documents(subtests): test = NamedDocument(name="DogSchema", coll="Dogs", ts=fixed_datetime) encoded = FaunaEncoder.encode(test) # should encode to a ref! - assert {"value": {"@ref": {"name": "DogSchema", "coll": {"@mod": "Dogs"}}}} == encoded + assert { + "value": { + "@ref": { + "name": "DogSchema", + "coll": { + "@mod": "Dogs" + } + } + } + } == encoded decoded = FaunaDecoder.decode(encoded["value"]) # refs will decode into references, not Documents assert NamedDocumentReference("Dogs", "DogSchema") == decoded @@ -360,7 +405,6 @@ def test_encode_long_conflicts(subtests): encoded = FaunaEncoder.encode(test) assert encoded == expected - with subtests.test(msg="decode @long conflict with long type"): expected = {"@long": 2147483649} test = {"@object": {"@long": {"@long": "2147483649"}}} @@ -421,7 +465,7 @@ def test_encode_date_time_conflicts(subtests): assert {"@date": date(2023, 2, 28)} == decoded with subtests.test(msg="decode @date conflict with other type"): - test = {"@object": {"@date": "bar"}} + test = {"@object": {"@date": "bar"}} decoded = FaunaDecoder.decode(test) assert {"@date": "bar"} == decoded @@ -441,7 +485,9 @@ def test_encode_date_time_conflicts(subtests): expected = { "object": { "@time": { - "value": {"@time": "2023-02-28T10:10:10.000010+00:00"} + "value": { + "@time": "2023-02-28T10:10:10.000010+00:00" + } } } } @@ -451,7 +497,7 @@ def test_encode_date_time_conflicts(subtests): with subtests.test(msg="encode @time conflict with other type"): test = {"@time": "bar"} - expected = {"object": {"@time": {"value":"bar"}}} + expected = {"object": {"@time": {"value": "bar"}}} encoded = FaunaEncoder.encode(test) assert encoded == expected @@ -468,13 +514,7 @@ def test_encode_date_time_conflicts(subtests): 10, tzinfo=timezone(timedelta(0), '+00:00')) } - test = { - "@object": { - "@time": { - "@time": "2023-02-28T10:10:10.000010+00:00" - } - } - } + test = {"@object": {"@time": {"@time": "2023-02-28T10:10:10.000010+00:00"}}} decoded = FaunaDecoder.decode(test) assert expected == decoded @@ -571,7 +611,9 @@ def test_encode_nested_conflict(subtests): "@time": { "object": { "@long": { - "value": {"@int": "10"} + "value": { + "@int": "10" + } } } } @@ -608,15 +650,12 @@ def test_encode_nested_conflict(subtests): decoded = FaunaDecoder.decode(test) assert expected == decoded + def test_encode_non_conflicting_at_prefix(subtests): with subtests.test(msg="encode non-conflicting @ prefix"): test = {"@foo": 10} - expected = { - "object": { - "@foo": {"value": {"@int": "10"}} - } - } + expected = {"object": {"@foo": {"value": {"@int": "10"}}}} encoded = FaunaEncoder.encode(test) assert encoded == expected @@ -628,22 +667,68 @@ def test_encode_non_conflicting_at_prefix(subtests): def test_encode_complex_objects( - subtests, - complex_untyped_object, - complex_typed_object, - complex_wire_encoded_object, + subtests, + complex_untyped_object, + complex_typed_object, + complex_wire_encoded_object, ): with subtests.test(msg="encode array with nesting"): doc_ref = DocumentReference.from_string("Array:123") - test = [1, ["hi"], doc_ref, fql("let d = ${foo}", foo=[{'inner': 3.1}]), {"foo": {"bar": 123}}] + test = [ + 1, ["hi"], doc_ref, + fql("let d = ${foo}", foo=[{ + 'inner': 3.1 + }]), { + "foo": { + "bar": 123 + } + } + ] expected = { - 'array': [ - {'value': {'@int': '1'}}, - {'array': [{'value': 'hi'}]}, - {'value': {'@ref': {'coll': {'@mod': 'Array'}, 'id': '123'}}}, - {'fql': ['let d = ', {'array': [{'object': {'inner': {'value': {'@double': '3.1'}}}}]}]}, - {'object': {'foo': {'object': {'bar': {'value': {'@int': '123'}}}}}} - ] + 'array': [{ + 'value': { + '@int': '1' + } + }, { + 'array': [{ + 'value': 'hi' + }] + }, { + 'value': { + '@ref': { + 'coll': { + '@mod': 'Array' + }, + 'id': '123' + } + } + }, { + 'fql': [ + 'let d = ', { + 'array': [{ + 'object': { + 'inner': { + 'value': { + '@double': '3.1' + } + } + } + }] + } + ] + }, { + 'object': { + 'foo': { + 'object': { + 'bar': { + 'value': { + '@int': '123' + } + } + } + } + } + }] } encoded = FaunaEncoder.encode(test) assert expected == encoded @@ -694,6 +779,7 @@ def test_encode_complex_objects( FaunaDecoder.decode(test) + def test_encode_query_builder_strings(subtests): with subtests.test(msg="pure string query"): actual = FaunaEncoder.encode(fql("let x = 11")) @@ -732,12 +818,18 @@ def test_encode_query_builder_with_value(subtests): "fql": [ "let x = ", { 'object': { - 'name': {'value': 'Dino'}, + 'name': { + 'value': 'Dino' + }, 'age': { - 'value': {'@int': '0'} + 'value': { + '@int': '0' + } }, 'birthdate': { - 'value': {'@date': '2023-02-24'} + 'value': { + '@date': '2023-02-24' + } } } } @@ -758,13 +850,19 @@ def test_encode_query_builder_sub_queries(subtests): "fql": [ "let x = ", { 'object': { - 'name': {'value': 'Dino'}, - 'age': { - 'value': {'@int': '0'} - }, - 'birthdate': { - 'value': {'@date': '2023-02-24'} - } + 'name': { + 'value': 'Dino' + }, + 'age': { + 'value': { + '@int': '0' + } + }, + 'birthdate': { + 'value': { + '@date': '2023-02-24' + } + } } } ]