Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[run]
branch = True
source = jsonpath_ng
source = jsonpath_ng, tests
237 changes: 61 additions & 176 deletions tests/test_create.py
Original file line number Diff line number Diff line change
@@ -1,184 +1,69 @@
import doctest
from collections import namedtuple
import copy
from contextlib import nullcontext as does_not_raise

import pytest

import jsonpath_ng
from jsonpath_ng.ext import parse

Params = namedtuple('Params', 'string initial_data insert_val target')


@pytest.mark.parametrize('string, initial_data, insert_val, target', [

Params(string='$.foo',
initial_data={},
insert_val=42,
target={'foo': 42}),

Params(string='$.foo.bar',
initial_data={},
insert_val=42,
target={'foo': {'bar': 42}}),

Params(string='$.foo[0]',
initial_data={},
insert_val=42,
target={'foo': [42]}),

Params(string='$.foo[1]',
initial_data={},
insert_val=42,
target={'foo': [{}, 42]}),

Params(string='$.foo[0].bar',
initial_data={},
insert_val=42,
target={'foo': [{'bar': 42}]}),

Params(string='$.foo[1].bar',
initial_data={},
insert_val=42,
target={'foo': [{}, {'bar': 42}]}),

Params(string='$.foo[0][0]',
initial_data={},
insert_val=42,
target={'foo': [[42]]}),

Params(string='$.foo[1][1]',
initial_data={},
insert_val=42,
target={'foo': [{}, [{}, 42]]}),

Params(string='foo[0]',
initial_data={},
insert_val=42,
target={'foo': [42]}),

Params(string='foo[1]',
initial_data={},
insert_val=42,
target={'foo': [{}, 42]}),

Params(string='foo',
initial_data={},
insert_val=42,
target={'foo': 42}),

# Initial data can be a list if we expect a list back
Params(string='[0]',
initial_data=[],
insert_val=42,
target=[42]),

Params(string='[1]',
initial_data=[],
insert_val=42,
target=[{}, 42]),

# Converts initial data to a list if necessary
Params(string='[0]',
initial_data={},
insert_val=42,
target=[42]),

Params(string='[1]',
initial_data={},
insert_val=42,
target=[{}, 42]),

Params(string='foo[?bar="baz"].qux',
initial_data={'foo': [
{'bar': 'baz'},
{'bar': 'bizzle'},
]},
insert_val=42,
target={'foo': [
{'bar': 'baz', 'qux': 42},
{'bar': 'bizzle'}
]}),
Params(string='[1].foo',
initial_data=[{'foo': 1},
{'bar': 2}],
insert_val=42,
target=[{'foo': 1},
{'foo': 42,
'bar': 2}],)
])
def test_update_or_create(string, initial_data, insert_val, target):
@pytest.mark.parametrize(
"string, initial_data, expected_result",
(
("$.foo", {}, {"foo": 42}),
("$.foo.bar", {}, {"foo": {"bar": 42}}),
("$.foo[0]", {}, {"foo": [42]}),
("$.foo[1]", {}, {"foo": [{}, 42]}),
("$.foo[0].bar", {}, {"foo": [{"bar": 42}]}),
("$.foo[1].bar", {}, {"foo": [{}, {"bar": 42}]}),
("$.foo[0][0]", {}, {"foo": [[42]]}),
("$.foo[1][1]", {}, {"foo": [{}, [{}, 42]]}),
("foo[0]", {}, {"foo": [42]}),
("foo[1]", {}, {"foo": [{}, 42]}),
("foo", {}, {"foo": 42}),
#
# Initial data can be a list if we expect a list back.
("[0]", [], [42]),
("[1]", [], [{}, 42]),
#
# Convert initial data to a list, if necessary.
("[0]", {}, [42]),
("[1]", {}, [{}, 42]),
#
(
'foo[?bar="baz"].qux',
{
"foo": [
{"bar": "baz"},
{"bar": "bizzle"},
]
},
{"foo": [{"bar": "baz", "qux": 42}, {"bar": "bizzle"}]},
),
("[1].foo", [{"foo": 1}, {"bar": 2}], [{"foo": 1}, {"foo": 42, "bar": 2}]),
),
)
def test_update_or_create(string, initial_data, expected_result):
jsonpath = parse(string)
result = jsonpath.update_or_create(initial_data, insert_val)
assert result == target


@pytest.mark.parametrize('string, initial_data, insert_val, target', [
# Slice not supported
Params(string='foo[0:1]',
initial_data={},
insert_val=42,
target={'foo': [42, 42]}),
# result is {'foo': {}}

# Filter does not create items to meet criteria
Params(string='foo[?bar="baz"].qux',
initial_data={},
insert_val=42,
target={'foo': [{'bar': 'baz', 'qux': 42}]}),
# result is {'foo': {}}

# Does not convert initial data to a dictionary
Params(string='foo',
initial_data=[],
insert_val=42,
target={'foo': 42}),
# raises TypeError

])
@pytest.mark.xfail
def test_unsupported_classes(string, initial_data, insert_val, target):
result = jsonpath.update_or_create(initial_data, 42)
assert result == expected_result


@pytest.mark.parametrize(
"string, initial_data, expectation",
(
# Slice not supported
("foo[0:1]", {}, does_not_raise()),
#
# Filter does not create items to meet criteria
('foo[?bar="baz"].qux', {}, does_not_raise()),
#
# Does not convert initial data to a dictionary
("foo", [], pytest.raises(TypeError)),
),
)
def test_unsupported_classes(string, initial_data, expectation):
copied_initial_data = copy.copy(initial_data)
jsonpath = parse(string)
result = jsonpath.update_or_create(initial_data, insert_val)
assert result == target


@pytest.mark.parametrize('string, initial_data, insert_val, target', [

Params(string='$.name[0].text',
initial_data={},
insert_val='Sir Michael',
target={'name': [{'text': 'Sir Michael'}]}),

Params(string='$.name[0].given[0]',
initial_data={'name': [{'text': 'Sir Michael'}]},
insert_val='Michael',
target={'name': [{'text': 'Sir Michael',
'given': ['Michael']}]}),

Params(string='$.name[0].prefix[0]',
initial_data={'name': [{'text': 'Sir Michael',
'given': ['Michael']}]},
insert_val='Sir',
target={'name': [{'text': 'Sir Michael',
'given': ['Michael'],
'prefix': ['Sir']}]}),

Params(string='$.birthDate',
initial_data={'name': [{'text': 'Sir Michael',
'given': ['Michael'],
'prefix': ['Sir']}]},
insert_val='1943-05-05',
target={'name': [{'text': 'Sir Michael',
'given': ['Michael'],
'prefix': ['Sir']}],
'birthDate': '1943-05-05'}),
])
def test_build_doc(string, initial_data, insert_val, target):
jsonpath = parse(string)
result = jsonpath.update_or_create(initial_data, insert_val)
assert result == target


def test_doctests():
results = doctest.testmod(jsonpath_ng)
assert results.failed == 0
with expectation:
result = jsonpath.update_or_create(initial_data, 42)
assert result != copied_initial_data