/*
Copyright 2013-2014 Immutables Authors and Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.immutables.fixture;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.ws.rs.POST;
import nonimmutables.GetterAnnotation;
import org.immutables.fixture.ImmutableSampleCopyOfTypes.ByBuilder;
import org.immutables.fixture.ImmutableSampleCopyOfTypes.ByConstructorAndWithers;
import org.immutables.fixture.style.ImmutableOptionalWithNullable;
import org.immutables.fixture.style.ImmutableOptionalWithoutNullable;
import org.junit.Test;
import static org.immutables.check.Checkers.check;
public class ValuesTest {
@Test
public void generateCopyAnnotations() throws Exception {
ImmutableGetters g = ImmutableGetters.builder().ab(0).cd("").ef(true).build();
check(g.getClass().getMethod("cd").isAnnotationPresent(POST.class));
check(g.getClass().getMethod("ef").getAnnotation(GetterAnnotation.class).value()).hasSize(2);
}
@Test
public void internCustomHashCode() {
ImmutableInternCustomHashCode i1 = ImmutableInternCustomHashCode.builder()
.a(1)
.build();
// customized hash code
check(i1.hashCode()).is(0);
// due to overriden equals and interning
check(i1).same(ImmutableInternCustomHashCode.builder()
.a(2)
.build());
}
@Test(expected = NullPointerException.class)
public void orderAndNullCheckForConstructor() {
ImmutableHostWithPort.of(1, null);
}
@Test
public void builderFrom() {
SampleValue sv1 = ImmutableSampleValue.builder()
.addC(1, 2)
.a(3)
.oi(1)
.build();
SampleValue sv2 = ImmutableSampleValue.builder()
.a(1)
.addC(3, 4)
.os("")
.build();
SampleValue svAll = ImmutableSampleValue.builder()
.from(sv1)
.from(sv2)
.build();
check(svAll.a()).is(1);
check(svAll.c()).isOf(1, 2, 3, 4);
check(svAll.oi().orElse(-1)).is(1);
check(svAll.os()).isOf("");
}
@Test
public void resetCollectionTest() {
OrderAttributeValue a = ImmutableOrderAttributeValue.builder()
.addNatural(0)
.natural(ImmutableList.of(3, 2, 4, 1))
.addReverse("")
.reverse(ImmutableList.of("a", "z", "b", "y"))
.putNavigableMap(1, "2")
.navigableMap(ImmutableMap.of(2, "2"))
.reverseMap(ImmutableMap.of("a", "a"))
.addNaturalMultiset(10, 10, 11)
.addReverseMultiset("x", "y", "y")
.naturalMultiset(ImmutableList.of(20, 13, 20))
.reverseMultiset(ImmutableList.of("w", "z", "z"))
.build();
OrderAttributeValue b = ImmutableOrderAttributeValue.builder()
.addNatural(3, 2, 4, 1)
.addReverse("a", "z", "b", "y")
.putNavigableMap(2, "2")
.putReverseMap("a", "a")
.addNaturalMultiset(20, 13, 20)
.addReverseMultiset("w", "z", "z")
.build();
check(a).is(b);
}
@Test
public void extendingBuilder() {
ExtendingInnerBuilderValue.Builder builder = new ExtendingInnerBuilderValue.Builder();
ExtendingInnerBuilderValue value = builder.addList("").build();
check(value.attribute()).is(1);
check(value.list()).isOf("");
}
@Test
public void defaultAsDefault() {
DefaultAsDefault d = ImmutableDefaultAsDefault.builder()
.b(1)
.build();
check(d.a()).is(1);
check(d.b()).is(1);
}
@Test
public void extendsBuilderIfaceValue() {
ExtendedBuilderInterface ifc = ExtendedBuilderInterface.builder()
.a(1)
.b(2)
.build();
check(ifc.a()).is(1);
check(ifc.b()).is(2);
}
@Test
public void ifaceValue() {
check(ImmutableIfaceValue.builder().number(1).build()).is(ImmutableIfaceValue.of(1));
}
@Test
public void ordering() {
OrderAttributeValue value = ImmutableOrderAttributeValue.builder()
.addNatural(3, 2, 4, 1)
.addReverse("a", "z", "b", "y")
.putNavigableMap(2, "2")
.putNavigableMap(1, "1")
.putReverseMap("a", "a")
.putReverseMap("b", "b")
.addNaturalMultiset(20, 13, 20)
.addReverseMultiset("w", "z", "z")
.build();
check(value.natural()).isOf(1, 2, 3, 4);
check(value.reverse()).isOf("z", "y", "b", "a");
check(value.navigableMap().keySet()).isOf(1, 2);
check(value.reverseMap().keySet()).isOf("b", "a");
check(value.naturalMultiset()).isOf(13, 20, 20);
check(value.reverseMultiset()).isOf("z", "z", "w");
}
@Test
public void primitiveDefault() {
check(ImmutablePrimitiveDefault.builder().build().def());
check(ImmutablePrimitiveDefault.builder().def(true).build().def());
check(!ImmutablePrimitiveDefault.builder().def(false).build().def());
}
@Test
public void sourceOrdering() {
SourceOrderingEntity v = ImmutableSourceOrderingEntity.builder()
.a(1)
.b(2)
.y(3)
.z(4)
.build();
check(v).hasToString("SourceOrderingEntity{z=4, y=3, b=2, a=1}");
}
@Test
public void requiredAttributesSetChecked() {
try {
ImmutableIfaceValue.builder().build();
check(false);
} catch (Exception ex) {
check(ex.getMessage()).contains("number");
}
}
@Test
public void auxiliary() {
ImmutableIfaceValue includesAuxiliary = ImmutableIfaceValue.builder().number(1).addAuxiliary("x").build();
ImmutableIfaceValue excludesAuxiliary = ImmutableIfaceValue.of(1);
check(includesAuxiliary).is(excludesAuxiliary);
check(includesAuxiliary.hashCode()).is(excludesAuxiliary.hashCode());
check(includesAuxiliary).asString().not().contains("auxiliary");
}
@Test
public void auxiliaryOnForcedSingleton() {
check(ImmutableAuxDefaultOnForcedSingleton.of().withAux(66).aux()).is(66);
}
@Test
public void builderInheritence() {
check(ImmutableSillyExtendedBuilder.builder().inheritedField);
}
@Test
public void nullable() {
ImmutableHasNullable hasNullable = ImmutableHasNullable.builder().build();
check(hasNullable.def()).isNull();
check(hasNullable.der()).isNull();
check(hasNullable.in()).isNull();
check(ImmutableHasNullable.of(null)).is(hasNullable);
check(ImmutableHasNullable.of()).is(hasNullable);
check(ImmutableHasNullable.of().hashCode()).is(hasNullable.hashCode());
check(hasNullable).hasToString("HasNullable{}");
}
@Test
public void nullableArray() {
NullableArray n1 = ImmutableNullableArray.builder()
.array((byte[]) null)
.build();
NullableArray n2 = ImmutableNullableArray.builder()
.build();
check(n1).is(n2);
check(n1.array()).isNull();
}
@Test
public void java8TypeAnnotation() throws Exception {
Method method = ImmutableHasTypeAnnotation.class.getMethod("str");
AnnotatedType returnType = method.getAnnotatedReturnType();
check(returnType.getAnnotation(TypeA.class)).notNull();
check(returnType.getAnnotation(TypeB.class)).notNull();
}
@Test
public void withMethods() {
ImmutableSillyValidatedBuiltValue value = ImmutableSillyValidatedBuiltValue.builder()
.value(-10)
.negativeOnly(true)
.build();
try {
value.withValue(10);
check(false);
} catch (Exception ex) {
}
check(value.withNegativeOnly(false).withValue(5).value()).is(5);
}
@Test
public void withMethodSetsAndMaps() {
ImmutableSillyMapHolder holder = ImmutableSillyMapHolder.builder()
.addZz(RetentionPolicy.CLASS)
.build();
check(holder.withZz(Collections.<RetentionPolicy>emptySet()).zz()).isEmpty();
check(holder.withHolder2(ImmutableMap.of(1, "")).holder2().size()).is(1);
}
@Test
public void lazyValue() {
SillyLazy v = ImmutableSillyLazy.of(new AtomicInteger());
check(v.counter().get()).is(0);
check(v.val1()).is(1);
check(v.counter().get()).is(1);
check(v.val2()).is(2);
check(v.val1()).is(1);
check(v.counter().get()).is(2);
}
@Test
public void packagePrivateClassGeneration() {
check(Modifier.isPublic(SillyEmpty.class.getModifiers()));
check(Modifier.isPublic(ImmutableSillyEmpty.class.getModifiers()));
check(!Modifier.isPublic(SillyExtendedBuilder.class.getModifiers()));
check(!Modifier.isPublic(ImmutableSillyExtendedBuilder.class.getModifiers()));
}
@Test
public void internedInstanceConstruction() {
check(ImmutableSillyInterned.of(1, 2)).is(ImmutableSillyInterned.of(1, 2));
check(ImmutableSillyInterned.of(1, 2)).same(ImmutableSillyInterned.of(1, 2));
check(ImmutableSillyInterned.of(1, 2)).not(ImmutableSillyInterned.of(2, 2));
check(ImmutableSillyInterned.builder()
.arg1(1)
.arg2(2)
.build())
.same(ImmutableSillyInterned.of(1, 2));
check(ImmutableSillyInterned.of(1, 2).hashCode()).is(ImmutableSillyInterned.of(1, 2).hashCode());
check(ImmutableSillyInterned.of(1, 2).hashCode()).not(ImmutableSillyInterned.of(2, 2).hashCode());
}
@Test(expected = IllegalStateException.class)
public void cannotBuildWrongInvariants() {
ImmutableSillyValidatedBuiltValue.builder()
.value(10)
.negativeOnly(true)
.build();
}
@Test
public void copyConstructor() {
ByBuilder wasCopiedByBuilder =
ImmutableSampleCopyOfTypes.ByBuilder.copyOf(new SampleCopyOfTypes.ByBuilder() {
@Override
public int value() {
return 2;
}
});
check(wasCopiedByBuilder.value()).is(2);
ByConstructorAndWithers wasCopiedByConstructorAndWithers =
ImmutableSampleCopyOfTypes.ByConstructorAndWithers.copyOf(new SampleCopyOfTypes.ByConstructorAndWithers() {
@Override
public int value() {
return 1;
}
@Override
public List<String> additional() {
return Arrays.asList("3");
}
});
check(wasCopiedByConstructorAndWithers.value()).is(1);
check(wasCopiedByConstructorAndWithers.additional()).isOf("3");
SampleCopyOfTypes.ByConstructorAndWithers value2 = ImmutableSampleCopyOfTypes.ByConstructorAndWithers.of(2);
check(ImmutableSampleCopyOfTypes.ByConstructorAndWithers.copyOf(value2))
.same(ImmutableSampleCopyOfTypes.ByConstructorAndWithers.copyOf(value2));
}
@Test
public void underwriteHashcodeToStringEquals() {
ImmutableUnderwrite v =
ImmutableUnderwrite.builder()
.value(1)
.build();
check(v.hashCode()).is(2);
check(v).hasToString("U");
check(v.equals("U"));
}
@Test
public void noUnderwriteInheritedHashcodeToStringEquals() {
ImmutableNoUnderwrite v =
ImmutableNoUnderwrite.builder()
.value(1)
.build();
check(v.hashCode()).not(2);
check(v.toString()).not("N");
check(!v.equals("N"));
}
@Test
public void recalculateDerivedOnCopy() {
ImmutableWitherDerived value = ImmutableWitherDerived.builder()
.set(1)
.build();
check(value.derived()).is(value.set() + 1);
value = value.withSet(2);
check(value.derived()).is(value.set() + 1);
}
@Test
public void canBuildCorrectInvariants() {
ImmutableSillyValidatedBuiltValue.builder()
.value(-10)
.negativeOnly(true)
.build();
ImmutableSillyValidatedBuiltValue.builder()
.value(10)
.negativeOnly(false)
.build();
ImmutableSillyValidatedBuiltValue.builder()
.value(-10)
.negativeOnly(false)
.build();
}
@Test(expected = IllegalStateException.class)
public void cannotConstructWithWrongInvariants() {
ImmutableSillyValidatedConstructedValue.of(10, true);
}
@Test
public void canConstructWithCorrectInvariants() {
ImmutableSillyValidatedConstructedValue.of(-10, true);
ImmutableSillyValidatedConstructedValue.of(10, false);
ImmutableSillyValidatedConstructedValue.of(-10, false);
}
@Test
public void optionalWhichAcceptsNullable() {
ImmutableOptionalWithNullable.builder()
.guavaOptional((String) null)
.javaOptional((String) null)
.javaOptionalInteger((Integer) null)
.build();
}
@Test(expected = NullPointerException.class)
public void optionalWhichDoesntAcceptsNullable() {
ImmutableOptionalWithoutNullable.builder()
.javaOptional((String) null)
.build();
}
@Test
public void properInitInternNoBuilder() {
ImmutableProperInitInternNoBuilder.of();
}
@Test
public void normalize() {
check(ImmutableNormalize.builder()
.value(-2)
.build()
.value()).is(2);
}
@Test
public void primitiveOptional() {
ImmutablePrimitiveOptionals.builder()
.v1(1)
.v2(0.2)
.v3(2)
.v4(true)
.v5("a")
.v6("b")
.v7(1)
.v8(0.1)
.v9(2L)
.build()
.withV1(2)
.withV2(0.3);
}
public void multipleCheck0() {
ImmutableMultipleChecks.C.builder().a(1).b(1).build();
}
@Test(expected = IllegalStateException.class)
public void multipleCheck1() {
ImmutableMultipleChecks.C.builder().a(0).b(1).build();
}
@Test(expected = IllegalStateException.class)
public void multipleCheck2() {
ImmutableMultipleChecks.C.builder().a(1).b(0).build();
}
@Test
public void redactedCompletely() {
ImmutableRedacted b = ImmutableRedacted.builder()
.id(2)
.code(1)
.data("a", "b")
.ssn("000-00-000")
.build();
check(b).hasToString("Redacted{id=2}");
}
@Test
public void redactedMask() {
ImmutableRedactedMask m = ImmutableRedactedMask.builder()
.code(1)
.build();
check(m).hasToString("RedactedMask{code=####}");
}
@Test
public void redactedMaskJdkOnly() {
ImmutableRedactedMaskJdkOnly m = ImmutableRedactedMaskJdkOnly.builder()
.code(1)
.build();
check(m).hasToString("RedactedMaskJdkOnly{code=$$$$}");
}
@Test
public void redactedMaskJdkOnlyOpt() {
ImmutableRedactedMaskJdkOnlyOpt m = ImmutableRedactedMaskJdkOnlyOpt.builder()
.code(1)
.build();
check(m).hasToString("RedactedMaskJdkOnlyOpt{code=????}");
}
}