package com.squareup.burst; import com.squareup.burst.annotation.Burst; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import static org.assertj.core.api.Assertions.assertThat; public class BurstableConstructorTest { enum First { } enum Second { } @Rule public final ExpectedException thrown = ExpectedException.none(); public static class None { } @Test public void noConstructor() { TestConstructor ctor = BurstableConstructor.findSingle(None.class); assertThat(ctor.getVariationTypes()).isEmpty(); } public static class Default { public Default() {} } @Test public void defaultConstructor() { TestConstructor ctor = BurstableConstructor.findSingle(Default.class); assertThat(ctor.getVariationTypes()).isEmpty(); } public static class One { public One(First first) {} } @Test public void singleParameterizedConstructor() { TestConstructor ctor = BurstableConstructor.findSingle(One.class); assertThat(ctor.getVariationTypes()).containsExactly(First.class); } public static class DefaultAndOne { public DefaultAndOne() {} public DefaultAndOne(First first) {} } @Test public void defaultAndParameterizedConstructor() { thrown.expect(IllegalStateException.class); thrown.expectMessage("too many parameterized constructors"); BurstableConstructor.findSingle(DefaultAndOne.class); } public static class NonPublicConstructor { NonPublicConstructor() {} } @Test public void nonPublic() { thrown.expect(IllegalStateException.class); thrown.expectMessage("requires at least 1 public constructor"); BurstableConstructor.findSingle(NonPublicConstructor.class); } public static class TooMany { public TooMany(First first) {} public TooMany(Second second) {} } @Test public void tooMany() { thrown.expect(IllegalStateException.class); thrown.expectMessage( "has too many parameterized constructors. Should only be 1 (with enum variations)."); BurstableConstructor.findSingle(TooMany.class); } public static class NonEnumInConstructor { public NonEnumInConstructor(Object first) {} } @Test public void nonEnumInConstructor() { TestConstructor ctor = BurstableConstructor.findSingle(NonEnumInConstructor.class); assertThat(ctor.getVariationTypes()).containsExactly(Object.class); } public static class NotAnEnumInConstructor { public NotAnEnumInConstructor(Object first) {} } @Test public void notAnEnumInConstructor() { TestConstructor ctor = BurstableConstructor.findSingle(NotAnEnumInConstructor.class); assertThat(ctor.getVariationTypes()).containsExactly(Object.class); } public static class DefaultWithField { @Burst First first; } @Test public void defaultConstructorWithField() { TestConstructor ctor = BurstableConstructor.findSingle(DefaultWithField.class); assertThat(ctor.getVariationTypes()).containsExactly(First.class); } public static class NoneWithField { @Burst First first; public NoneWithField() {} } @Test public void singleEmptyConstructorWithField() { TestConstructor ctor = BurstableConstructor.findSingle(NoneWithField.class); assertThat(ctor.getVariationTypes()).containsExactly(First.class); } public static class MultipleFields { @Burst First first; @Burst Second second; } @Test public void emptyConstructorMultipleFields() { TestConstructor ctor = BurstableConstructor.findSingle(MultipleFields.class); assertThat(ctor.getVariationTypes()).containsOnly(First.class, Second.class); } public static class OneWithField { @Burst Second second; public OneWithField(First first) {} } @Test public void singleParameterizedConstructorWithField() { thrown.expectMessage( "has a parameterized constructor, so cannot also be parameterized on fields"); BurstableConstructor.findSingle(OneWithField.class); } public static class PrivateField { @Burst private First first; } @Test public void privateAnnotatedField() { TestConstructor ctor = BurstableConstructor.findSingle(PrivateField.class); assertThat(ctor.getVariationTypes()).containsExactly(First.class); } public static class InheritedField extends PrivateField { @Burst Second second; } @Test public void inheritedField() { TestConstructor ctor = BurstableConstructor.findSingle(InheritedField.class); assertThat(ctor.getVariationTypes()).containsOnly(First.class, Second.class); } public static class StaticField { @Burst static First first; } @Test public void StaticField() { thrown.expect(IllegalStateException.class); thrown.expectMessage("Burstable field must not be static"); BurstableConstructor.findSingle(StaticField.class); } public static class FinalField { @Burst final First first = null; } @Test public void finalField() { thrown.expect(IllegalStateException.class); thrown.expectMessage("Burstable field must not be final"); BurstableConstructor.findSingle(FinalField.class); } public static class NotAnEnumField { @Burst Object first; } @Test public void notAnEnumField() { TestConstructor ctor = BurstableConstructor.findSingle(NotAnEnumField.class); assertThat(ctor.getVariationTypes()).containsExactly(Object.class); } public static class UnannotatedField { First first; @Burst Second second; } @Test public void unannotatedField() { TestConstructor ctor = BurstableConstructor.findSingle(UnannotatedField.class); assertThat(ctor.getVariationTypes()).containsExactly(Second.class); } }