### Question:
ElmChoiceBuilder implements ElmTypeDef { public ElmFunctionBuilder decoder() { val typeName = spec.typeName(); val name = decoderName(); val declaration = "Json.Decode.Decoder " + typeName; val params = ""; val firstLines = line( "Json.Decode.field \"__tagged\" Json.Decode.string", " |> Json.Decode.andThen", " (\\str ->", " case str of" ); val fieldEncoders = linesOf( spec .sourceSpec() .choices .stream() .map(toFieldDecoder(typeName))) .indent(4); val lastLines = line( " somethingElse ->", " Json.Decode.fail <| \"Unknown tagged: \" ++ somethingElse", ")"); val body = firstLines.append(fieldEncoders).append(lastLines); val encoder = new ElmFunctionBuilder(name, declaration, params, body); return encoder; } ElmChoiceBuilder(ElmChoiceSpec spec); String typeName(); String encoderName(); String decoderName(); ILines typeDefinition(); ElmFunctionBuilder encoder(); ElmFunctionBuilder decoder(); String toElmCode();  }### Answer:
@Test public void testChoiceTypeDecoder() { val builder = setupBuilder(); assertEquals( "loginStatusDecoder : Json.Decode.Decoder LoginStatus\n" + "loginStatusDecoder = \n" + " Json.Decode.field \"__tagged\" Json.Decode.string\n" + " |> Json.Decode.andThen\n" + " (\\str ->\n" + " case str of\n" + " \"LoggedIn\" ->\n" + " Json.Decode.succeed LoggedIn\n" + " |> Json.Decode.Pipeline.required \"name\" Json.Decode.string\n" + " |> Json.Decode.Pipeline.required \"age\" Json.Decode.int\n" + " |> Json.Decode.Pipeline.required \"years\" (Json.Decode.list Json.Decode.int)\n" + " |> Json.Decode.Pipeline.optional \"wealth\" (Json.Decode.nullable Json.Decode.float) Nothing\n" + " |> Json.Decode.Pipeline.required \"user\" userDecoder\n" + " \n" + " \"LoggedOut\" ->\n" + " Json.Decode.succeed LoggedOut\n" + " \n" + " somethingElse ->\n" + " Json.Decode.fail <| \"Unknown tagged: \" ++ somethingElse\n" + " )", builder.decoder().toText()); }