package cz.habarta.typescript.generator; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import java.util.List; import org.junit.Assert; import org.junit.Test; public class TaggedUnionsTest { private static class Geometry { public List<Shape> shapes; } @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "kind") @JsonSubTypes({ @JsonSubTypes.Type(Square.class), @JsonSubTypes.Type(Rectangle.class), @JsonSubTypes.Type(Circle.class), }) private static class Shape { } @JsonTypeName("square") private static class Square extends Shape { public double size; } @JsonTypeName("rectangle") private static class Rectangle extends Shape { public double width; public double height; } @JsonTypeName("circle") private static class Circle extends Shape { public double radius; } @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "kind") @JsonSubTypes({ @JsonSubTypes.Type(CSquare2.class), @JsonSubTypes.Type(CRectangle2.class), @JsonSubTypes.Type(CCircle2.class), }) private static interface IShape2 { } private static interface IQuadrilateral2 extends IShape2 { } @JsonTypeName("square") private static class CSquare2 implements IQuadrilateral2 { public double size; } @JsonTypeName("rectangle") private static class CRectangle2 implements IQuadrilateral2 { public double width; public double height; } @JsonTypeName("circle") private static class CCircle2 implements IShape2 { public double radius; } @Test public void testTaggedUnions() { final Settings settings = TestUtils.settings(); final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(Geometry.class)); final String expected = ( "\n" + "interface Geometry {\n" + " shapes: ShapeUnion[];\n" + "}\n" + "\n" + "interface Shape {\n" + " kind: 'square' | 'rectangle' | 'circle';\n" + "}\n" + "\n" + "interface Square extends Shape {\n" + " kind: 'square';\n" + " size: number;\n" + "}\n" + "\n" + "interface Rectangle extends Shape {\n" + " kind: 'rectangle';\n" + " width: number;\n" + " height: number;\n" + "}\n" + "\n" + "interface Circle extends Shape {\n" + " kind: 'circle';\n" + " radius: number;\n" + "}\n" + "\n" + "type ShapeUnion = Square | Rectangle | Circle;\n" + "" ).replace('\'', '"'); Assert.assertEquals(expected, output); } @Test public void testTaggedUnionsWithInterfaces() { final Settings settings = TestUtils.settings(); final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(IShape2.class)); final String expected = ( "\n" + "interface IShape2 {\n" + " kind: 'circle' | 'square' | 'rectangle';\n" + "}\n" + "\n" + "interface CSquare2 extends IQuadrilateral2 {\n" + " kind: 'square';\n" + " size: number;\n" + "}\n" + "\n" + "interface CRectangle2 extends IQuadrilateral2 {\n" + " kind: 'rectangle';\n" + " width: number;\n" + " height: number;\n" + "}\n" + "\n" + "interface CCircle2 extends IShape2 {\n" + " kind: 'circle';\n" + " radius: number;\n" + "}\n" + "\n" + "interface IQuadrilateral2 extends IShape2 {\n" + "}\n" + "\n" + "type IShape2Union = CSquare2 | CRectangle2 | CCircle2;\n" + "" ).replace('\'', '"'); Assert.assertEquals(expected, output); } @Test public void testTaggedUnionsDisabled() { final Settings settings = TestUtils.settings(); settings.disableTaggedUnions = true; final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(Geometry.class)); final String expected = ( "\n" + "interface Geometry {\n" + " shapes: Shape[];\n" + "}\n" + "\n" + "interface Shape {\n" + " kind: 'square' | 'rectangle' | 'circle';\n" + "}\n" + "\n" + "interface Square extends Shape {\n" + " kind: 'square';\n" + " size: number;\n" + "}\n" + "\n" + "interface Rectangle extends Shape {\n" + " kind: 'rectangle';\n" + " width: number;\n" + " height: number;\n" + "}\n" + "\n" + "interface Circle extends Shape {\n" + " kind: 'circle';\n" + " radius: number;\n" + "}\n" + "" ).replace('\'', '"'); Assert.assertEquals(expected, output); } }