OpenHFT / Chronicle-Wire

A Low Garbage Java Serialisation Library that supports multiple formats
http://chronicle.software
Apache License 2.0
506 stars 123 forks source link

Fixed typed JSON with Maps, Lists and Boxed Types #324

Closed RobAustin closed 2 years ago

RobAustin commented 2 years ago

The following test fails with typed JSON

import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.Collection;

import static java.util.Collections.singletonMap;

@RunWith(value = Parameterized.class)
public class JSONTypesWithMaps {

    private final boolean useTypes;

    @Parameterized.Parameters(name = "useTypes={0}")
    public static Collection<Object[]> wireTypes() {
        return Arrays.asList(
                new Object[]{true},
                new Object[]{false}
        );
    }

    public JSONTypesWithMaps(boolean useTypes) {
        this.useTypes = useTypes;
    }

    static class F1 {
        private String surname;
        private int car;

        public F1(String surname, int car) {
            this.surname = surname;
            this.car = car;
        }
    }

    @Test
    public void test() {

        final JSONWire jsonWire = new JSONWire()
                .useTypes(useTypes);

        jsonWire.getValueOut()
                .object(singletonMap("Lewis", new F1("Hamilton", 44)));

        final String actual = jsonWire.getValueIn().object().toString();
        Assert.assertEquals("{Lewis={surname=Hamilton, car=44}}", actual);
    }
}

and for lists see

**
 * relates to https://github.com/OpenHFT/Chronicle-Wire/issues/324
 */
@RunWith(value = Parameterized.class)
public class JSONWireWithLists {

    private final boolean useTypes;

    @Parameterized.Parameters(name = "useTypes={0}")
    public static Collection<Object[]> wireTypes() {
        return Arrays.asList(
                new Object[]{true},
                new Object[]{false}
        );
    }

    public JSONWireWithLists(boolean useTypes) {
        this.useTypes = useTypes;
    }

    static class F1 {
        private String surname;
        private int car;

        public F1(String surname, int car) {
            this.surname = surname;
            this.car = car;
        }
    }

    @Test
    public void test() {

        final JSONWire jsonWire = new JSONWire()
                .useTypes(useTypes);

        final List<F1> drivers = Arrays.asList(new F1("Hamilton", 44), new F1("Verstappen", 33));
        jsonWire.getValueOut().object(drivers);

        final String actual = jsonWire.getValueIn().object().toString();
        Assert.assertEquals("[{surname=Hamilton, car=44}, {surname=Verstappen, car=33}]", actual);
    }
}

for boxed types

package net.openhft.chronicle.wire;

import net.openhft.chronicle.core.pool.ClassAliasPool;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.Collection;

/**
 * relates to https://github.com/OpenHFT/Chronicle-Wire/issues/324
 */
@Ignore
@RunWith(value = Parameterized.class)
public class JSONTypesWithEnumsAndBoxedTypes {

    private final boolean useTypes;

    @Parameterized.Parameters(name = "useTypes={0}")
    public static Collection<Object[]> wireTypes() {
        return Arrays.asList(
                new Object[]{true},
                new Object[]{false}
        );
    }

    public JSONTypesWithEnumsAndBoxedTypes(boolean useTypes) {
        this.useTypes = useTypes;
    }

    enum Location {
        PITS, TRACK, GRAVEL
    }

    static class F1 extends AbstractMarshallableCfg {

        private String surname;

        // change this to and int from a Integer and it will work !
        private Integer car;
        private Location location;

        public F1(String surname, int car, Location location) {
            this.surname = surname;
            this.car = car;
            this.location = location;
        }
    }

    @Test
    public void test() {
        ClassAliasPool.CLASS_ALIASES.addAlias(F1.class);
        final JSONWire jsonWire = new JSONWire()
                .useTypes(useTypes);

        jsonWire.getValueOut()
                .object(new F1("Hamilton", 44, Location.TRACK));

        final String actual = jsonWire.getValueIn().object().toString();
        Assert.assertTrue(actual.contains("TRACK"));
    }
}
minborg commented 2 years ago

One of the problems with the generator is that it does not output closing brackets (i.e. }) for nested typed objects. This will result in unparsable data.