Как проверить, что элементы в json отсортированы по конкретному признаку?

Как проверить, что элементы в json отсортированы по конкретному признаку, например по цвету:
Мне надо что-то типа
assert(isSort([{id:5, color:red}, {id:8, color:blue}{id:9, color:blue}{id:2, color:green}])) = false

assert(isSort([{id:9, color:blue}, {id:8, color:blue}{id:2, color:green}{id:5, color:red}])) = true

Нужно решение на groovy или java или намеки, как это сделать…

Для чего это нужно? Зачем проверять сортировку в JSON-объекте, который по сути не гарантирует порядок элементов

1 лайк

Но если очень хочется, то наверное нужно юзать какой нибудь SortedMap ? (в джавах не очень разбираюсь :smile: ) Почитайте что то вроде этого.

Хочется проверить что сортировка на сервере работает как надо, то етьс я делаю запрос, получаю json с элементами и проверяю что сортировка там действительно соблюдена. Я пишу тесты на АПИ где много сортировок на сервере. И как их проверять? Хочется иметь не только смоук тесты…

Сортировка может быть сохранена в массиве, а не в объекте.

Для парсинга json есть разные библиотеки, можно выбирать “на вкус”.
Не рекомендую Jackson, который любят разработчики, но под него надо создавать полноценные маппинги, что для теста, скорее всего, излишне.
Есть стандартная библиотека org.json (http://www.json.org/java/).
Есть com.google.gson (GitHub - tflhyl/google-gson: Fork from https://code.google.com/p/google-gson), довольно приятный в использвании.
В Groovy, возможно, есть что-то своё.

Сценарий обычно такой: создаем классы, на которые можно отобразить структуру JSON’а, парсим и далее проверяем готовые объекты в Java.

То есть сначала все равно придется делать “образцовую структуру”? Если она у меня динамическая…я думала просто сравнивать два элемента по признаку и если один больше другого, то возвращать false, как то так…

Каким-нибудь легким изящным скриптиком =)

Не важно, динамическая она или нет. Полная структура объекта известна? Думаю да.
Когда будете читать из json в pojo, отсутствующие элементы просто будут null. Но ведь условие для сравнения вы задаете вручную, так? Т.е. если вы ассертите корректность сортировки по какому-то полю, вам однозначно известно, что оно != null, иначе весь смысл затеи теряется.

В похожей теме я привел пример, как распарсить json в POJO. Там же я намекнул, что стримы позволяют делать вам все что угодно с коллекциями, включая задания кастомных comparators. Для определения валидности порядка, вам нужно для начала привести коллекцию в отсортированный вид по цвету, аля expected result.

List<MyPojo> sortedPojo firstPojo.stream()
    .sorted((ob1, ob2) -> ob1.getColor().compareTo(ob2.getColor()))
    .collect(toList());

Затем, можно воспользоваться готовым методом isEqualList, входящим в состав апачевского ListUtils, для сравнения двух коллекций по цвету:

assertTrue(isEqualList(firstPojo.stream().map(MyPojo::getColor).collect(toList()), 
    sortedPojo.stream().map(MyPojo::getColor).collect(toList())));

Таким образом я могу легко по любомум кастомному признаку делать сравнение, так ведь? Вроде бы звучит досточно хорошо…

Можно и скриптиком, а при условии, что эта структура нигде больше не пригодится. Тогда есть резон не засорять тесты лишними классами. В общем, все в Ваших руках. Всегда можно распарсить динамически и поэлементно, если это выгодно. Я в Java в таких случаях использую JsonParser из Gson. А в другой ветке уже давали ссылку на JsonSlurper для Groovy.

Да, в выше приведенном примере достаточно передать любое из доступных свойств comparator’у.

List<MyPojo> sortedPojo firstPojo.stream()
     // getId(), getMagicWand(), etc.
    .sorted((ob1, ob2) -> ob1.getStatus().compareTo(ob2.getStatus()))
    .collect(toList());

Более того, вы можете вообще вынести comparator в качестве параметра метода сортировки:

public List<MyPojo> getSortedList(List<MyPojo> input, Comparator<MyPojo> comparator) {
    return input.stream().sorted(comparator).collect(toList());
}

// call
List<MyPojo> sortedByColors = getSortedList(firstPojo, 
        (ob1, ob2) -> ob1.getColor().compareTo(ob2.getColor()));

List<MyPojo> sortedByStatus = getSortedList(firstPojo, 
        (ob1, ob2) -> ob1.getStatus().compareTo(ob2.getStatus()));
1 лайк