### Question:
ElmChoiceBuilder implements ElmTypeDef { public ElmFunctionBuilder encoder() { val typeName = spec.typeName(); val name = encoderName(); val params = camelName(); val declaration = typeName + " -> Json.Encode.Value"; val caseExpr = line("case " + name + " of"); val choices = linesOf( spec.sourceSpec() .choices.stream() .map(toCaseField)); val body = caseExpr.append(choices.indent(1)); return new ElmFunctionBuilder(name, declaration, params, body); } ElmChoiceBuilder(ElmChoiceSpec spec); String typeName(); String encoderName(); String decoderName(); ILines typeDefinition(); ElmFunctionBuilder encoder(); ElmFunctionBuilder decoder(); String toElmCode();  }### Answer:
@Test public void testChoiceTypeEncoder() { val builder = setupBuilder(); assertEquals( "loginStatusEncoder : LoginStatus -> Json.Encode.Value\n" + "loginStatusEncoder loginStatus = \n" + " case loginStatusEncoder of\n" + " LoggedIn name age years wealth user ->\n" + " Json.Encode.object\n" + " [ ( \"__tagged\", Json.Encode.string \"LoggedIn\" )\n" + " , ( \"name\", Json.Encode.string name )\n" + " , ( \"age\", Json.Encode.int age )\n" + " , ( \"years\", Json.Encode.list Json.Encode.int years )\n" + " , ( \"wealth\", Maybe.withDefault Json.Encode.null (Maybe.map Json.Encode.float wealth) )\n" + " , ( \"user\", userEncoder user )\n" + " ]\n" + " LoggedOut ->\n" + " Json.Encode.object\n" + " [ ( \"__tagged\", Json.Encode.string \"LoggedOut\" )\n" + " ]", builder.encoder().toText()); }