org.jboss.forge.test.roaster.model.util.RefactoryTest.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.forge.test.roaster.model.util.RefactoryTest.java

Source

/*
 * Copyright 2012 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Eclipse Public License version 1.0, available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.jboss.forge.test.roaster.model.util;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.jboss.forge.roaster.Roaster;
import org.jboss.forge.roaster.model.source.FieldSource;
import org.jboss.forge.roaster.model.source.JavaClassSource;
import org.jboss.forge.roaster.model.source.MethodSource;
import org.jboss.forge.roaster.model.util.Refactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
 * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
 */
public class RefactoryTest {
    JavaClassSource javaClass;

    @BeforeEach
    public void before() {
        javaClass = Roaster.parse(JavaClassSource.class,
                "import java.util.Set; public class Foo { private int foo; private String firstName; private Set<String> names; private final int bar; }");
    }

    @Test
    public void testAddGettersAndSetters() {
        FieldSource<JavaClassSource> field = javaClass.getField("foo");
        Refactory.createGetterAndSetter(javaClass, field);

        List<MethodSource<JavaClassSource>> methods = javaClass.getMethods();
        MethodSource<JavaClassSource> getter = methods.get(0);
        MethodSource<JavaClassSource> setter = methods.get(1);

        assertEquals("getFoo", getter.getName());
        assertTrue(getter.getParameters().isEmpty());
        assertEquals("setFoo", setter.getName());
        assertFalse(javaClass.hasSyntaxErrors());
    }

    @Test
    public void testAddGettersAndSettersCamelCase() {
        FieldSource<JavaClassSource> field = javaClass.getField("firstName");
        Refactory.createGetterAndSetter(javaClass, field);

        List<MethodSource<JavaClassSource>> methods = javaClass.getMethods();
        MethodSource<JavaClassSource> getter = methods.get(0);
        MethodSource<JavaClassSource> setter = methods.get(1);

        assertEquals("getFirstName", getter.getName());
        assertTrue(getter.getParameters().isEmpty());
        assertEquals("setFirstName", setter.getName());
        assertFalse(javaClass.hasSyntaxErrors());
    }

    @Test
    public void testAddGetterNotSetterForFinalField() {
        FieldSource<JavaClassSource> field = javaClass.getField("bar");
        Refactory.createGetterAndSetter(javaClass, field);

        List<MethodSource<JavaClassSource>> methods = javaClass.getMethods();
        MethodSource<JavaClassSource> getter = methods.get(0);

        assertEquals("getBar", getter.getName());
        assertEquals(1, methods.size());
        assertFalse(javaClass.hasSyntaxErrors());
    }

    @Test
    public void testAddGettersAndSettersGeneric() {
        FieldSource<JavaClassSource> field = javaClass.getField("names");
        Refactory.createGetterAndSetter(javaClass, field);

        List<MethodSource<JavaClassSource>> methods = javaClass.getMethods();
        MethodSource<JavaClassSource> getter = methods.get(0);
        MethodSource<JavaClassSource> setter = methods.get(1);

        assertEquals("getNames", getter.getName());
        assertTrue(getter.getParameters().isEmpty());
        assertEquals("Set", getter.getReturnType().getName());
        assertEquals("Set<String>", getter.getReturnType().toString());
        assertEquals("setNames", setter.getName());
        assertFalse(setter.getParameters().isEmpty());
        assertEquals("Set<String>", setter.getParameters().get(0).getType().toString());
        assertEquals("Set", setter.getParameters().get(0).getType().getName());
        assertTrue(setter.getParameters().get(0).getType().isParameterized());
        assertEquals("String", setter.getParameters().get(0).getType().getTypeArguments().get(0).getName());
        assertFalse(javaClass.hasSyntaxErrors());
    }

    @Test
    public void testCreateToStringFromFields() {
        assertFalse(javaClass.hasMethodSignature("toString"));
        Refactory.createToStringFromFields(javaClass);
        assertTrue(javaClass.hasMethodSignature("toString"));
        assertTrue(javaClass.getMethod("toString").getBody().contains("return"));
        assertTrue(javaClass.getMethod("toString").getBody().contains("firstName != null"));
        assertFalse(javaClass.hasSyntaxErrors());
    }

    @Test
    public void testCreateHashCodeAndEqualsForStatics() {
        JavaClassSource aClass = Roaster.parse(JavaClassSource.class,
                "public class Foo { private static boolean flag;}");
        FieldSource<JavaClassSource> booleanField = aClass.getField("flag");
        assertThrows(IllegalArgumentException.class, () -> Refactory.createHashCodeAndEquals(aClass, booleanField));
    }

    @Test
    public void testCreateHashCodeForStatics() {
        JavaClassSource aClass = Roaster.parse(JavaClassSource.class,
                "public class Foo { private static boolean flag;}");
        FieldSource<JavaClassSource> booleanField = aClass.getField("flag");
        assertThrows(IllegalArgumentException.class, () -> Refactory.createHashCode(aClass, booleanField));
    }

    @Test
    public void testCreateEqualsForStatics() {
        JavaClassSource aClass = Roaster.parse(JavaClassSource.class,
                "public class Foo { private static boolean flag;}");
        FieldSource<JavaClassSource> booleanField = aClass.getField("flag");
        assertThrows(IllegalArgumentException.class, () -> Refactory.createEquals(aClass, booleanField));
    }

    @Test
    public void testCreateHashCodeAndEqualsForPrimitives() {
        JavaClassSource aClass = Roaster.parse(JavaClassSource.class,
                "public class Foo { private boolean aBoolean; private byte aByte; private char aChar; private short aShort; private int anInt; private long aLong; private float aFloat; private double aDouble; }");
        FieldSource<JavaClassSource> booleanField = aClass.getField("aBoolean");
        FieldSource<JavaClassSource> byteField = aClass.getField("aByte");
        FieldSource<JavaClassSource> charField = aClass.getField("aChar");
        FieldSource<JavaClassSource> shortField = aClass.getField("aShort");
        FieldSource<JavaClassSource> intField = aClass.getField("anInt");
        FieldSource<JavaClassSource> longField = aClass.getField("aLong");
        FieldSource<JavaClassSource> floatField = aClass.getField("aFloat");
        FieldSource<JavaClassSource> doubleField = aClass.getField("aDouble");
        Refactory.createHashCodeAndEquals(aClass, booleanField, byteField, charField, shortField, intField,
                longField, floatField, doubleField);
        List<MethodSource<JavaClassSource>> methods = aClass.getMethods();
        assertTrue(aClass.getMethods().size() == 2);
        MethodSource<JavaClassSource> equals = methods.get(0);
        MethodSource<JavaClassSource> hashcode = methods.get(1);
        assertEqualsForPrimitives(equals);
        assertHashCodeForPrimitives(hashcode);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        aClass.removeMethod(hashcode);
        assertTrue(aClass.getMethods().size() == 0);

        // equals only
        Refactory.createEquals(aClass, booleanField, byteField, charField, shortField, intField, longField,
                floatField, doubleField);
        methods = aClass.getMethods();
        assertTrue(aClass.getMethods().size() == 1);
        equals = methods.get(0);
        assertEqualsForPrimitives(equals);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        assertTrue(aClass.getMethods().size() == 0);
        // hashCode only
        Refactory.createHashCode(aClass, booleanField, byteField, charField, shortField, intField, longField,
                floatField, doubleField);
        assertTrue(aClass.getMethods().size() == 1);
        methods = aClass.getMethods();
        equals = methods.get(0);
        assertHashCodeForPrimitives(equals);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        assertTrue(aClass.getMethods().size() == 0);
    }

    private void assertEqualsForPrimitives(MethodSource<JavaClassSource> equals) {
        assertEquals("equals", equals.getName());
        assertEquals(1, equals.getParameters().size());
        assertThat(equals.getBody()).contains("if (aBoolean != other.aBoolean) {\n  return false;\n}");
        assertThat(equals.getBody()).contains("if (aByte != other.aByte) {\n  return false;\n}");
        assertThat(equals.getBody()).contains("if (aChar != other.aChar) {\n  return false;\n}");
        assertThat(equals.getBody()).contains("if (aShort != other.aShort) {\n  return false;\n}");
        assertThat(equals.getBody()).contains("if (anInt != other.anInt) {\n  return false;\n}");
        assertThat(equals.getBody()).contains("if (aLong != other.aLong) {\n  return false;\n}");
        assertThat(equals.getBody()).contains(
                "if (Float.floatToIntBits(aFloat) != Float.floatToIntBits(other.aFloat)) {\n  return false;\n}");
        assertThat(equals.getBody()).contains(
                "if (Double.doubleToLongBits(aDouble) != Double.doubleToLongBits(other.aDouble)) {\n  return false;\n}");
    }

    private void assertHashCodeForPrimitives(MethodSource<JavaClassSource> hashcode) {
        assertEquals("hashCode", hashcode.getName());
        assertEquals(0, hashcode.getParameters().size());
        assertEquals("int", hashcode.getReturnType().getName());
        assertThat(hashcode.getBody()).contains("result=prime * result + (aBoolean ? 1231 : 1237);");
        assertThat(hashcode.getBody()).contains("result=prime * result + aByte;");
        assertThat(hashcode.getBody()).contains("result=prime * result + aChar;");
        assertThat(hashcode.getBody()).contains("result=prime * result + aShort;");
        assertThat(hashcode.getBody()).contains("result=prime * result + anInt;");
        assertThat(hashcode.getBody()).contains("result=prime * result + (int)(aLong ^ (aLong >>> 32));");
        assertThat(hashcode.getBody()).contains("result=prime * result + Float.floatToIntBits(aFloat);");
        assertThat(hashcode.getBody()).contains("long temp;");
        assertThat(hashcode.getBody()).contains("temp=Double.doubleToLongBits(aDouble);");
        assertThat(hashcode.getBody()).contains("prime * result + (int)(temp ^ (temp >>> 32));");

    }

    @Test
    public void testCreateHashCodeAndEqualsForArrays() {
        JavaClassSource aClass = Roaster.parse(JavaClassSource.class,
                "public class Foo { private boolean[] flags; private Object[] objects;}");
        FieldSource<JavaClassSource> primitiveArrayField = aClass.getField("flags");
        FieldSource<JavaClassSource> objectArrayField = aClass.getField("objects");
        Refactory.createHashCodeAndEquals(aClass, primitiveArrayField, objectArrayField);

        List<MethodSource<JavaClassSource>> methods = aClass.getMethods();
        assertTrue(aClass.getMethods().size() == 2);
        MethodSource<JavaClassSource> equals = methods.get(0);
        MethodSource<JavaClassSource> hashcode = methods.get(1);
        assertHashCodeForArrays(hashcode);
        assertEqualsForArrays(equals);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        aClass.removeMethod(hashcode);
        assertTrue(aClass.getMethods().size() == 0);

        Refactory.createEquals(aClass, primitiveArrayField, objectArrayField);
        assertTrue(aClass.getMethods().size() == 1);
        methods = aClass.getMethods();
        equals = methods.get(0);
        assertEqualsForArrays(equals);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        assertTrue(aClass.getMethods().size() == 0);

        Refactory.createHashCode(aClass, primitiveArrayField, objectArrayField);
        assertTrue(aClass.getMethods().size() == 1);
        methods = aClass.getMethods();
        hashcode = methods.get(0);
        assertHashCodeForArrays(hashcode);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(hashcode);
        assertTrue(aClass.getMethods().size() == 0);

    }

    private void assertHashCodeForArrays(MethodSource<JavaClassSource> hashcode) {
        assertEquals("hashCode", hashcode.getName());
        assertEquals(0, hashcode.getParameters().size());
        assertEquals("int", hashcode.getReturnType().getName());
        assertThat(hashcode.getBody().contains("result=prime * result + java.util.Arrays.hashCode(flags);"));
        assertThat(hashcode.getBody().contains("result=prime * result + java.util.Arrays.hashCode(objects);"));
    }

    private void assertEqualsForArrays(MethodSource<JavaClassSource> equals) {
        assertEquals("equals", equals.getName());
        assertEquals(1, equals.getParameters().size());
        assertThat(equals.getBody())
                .contains("if (!java.util.Arrays.equals(flags,other.flags)) {\n  return false;\n}");
        assertThat(equals.getBody())
                .contains("if (!java.util.Arrays.equals(objects,other.objects)) {\n  return false;\n}");
    }

    @Test
    public void testCreateHashCodeAndEqualsForObjects() {
        JavaClassSource aClass = Roaster.parse(JavaClassSource.class,
                "import java.util.Date; public class Foo { private Object object; private Date date;}");
        FieldSource<JavaClassSource> identityBasedField = aClass.getField("object");
        FieldSource<JavaClassSource> nonIdentityBasedField = aClass.getField("date");
        Refactory.createHashCodeAndEquals(aClass, identityBasedField, nonIdentityBasedField);

        List<MethodSource<JavaClassSource>> methods = aClass.getMethods();
        assertTrue(aClass.getMethods().size() == 2);
        MethodSource<JavaClassSource> equals = methods.get(0);
        MethodSource<JavaClassSource> hashcode = methods.get(1);
        assertHashCodeForObjects(hashcode);
        assertEqualsForObjects(equals);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        aClass.removeMethod(hashcode);
        assertTrue(aClass.getMethods().size() == 0);

        Refactory.createHashCode(aClass, identityBasedField, nonIdentityBasedField);
        assertTrue(aClass.getMethods().size() == 1);
        methods = aClass.getMethods();
        hashcode = methods.get(0);
        assertHashCodeForObjects(hashcode);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(hashcode);
        assertTrue(aClass.getMethods().size() == 0);

        Refactory.createEquals(aClass, identityBasedField, nonIdentityBasedField);
        assertTrue(aClass.getMethods().size() == 1);
        methods = aClass.getMethods();
        equals = methods.get(0);
        assertEqualsForObjects(equals);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        assertEquals(0, aClass.getMethods().size());

    }

    private void assertHashCodeForObjects(MethodSource<JavaClassSource> hashcode) {
        assertEquals("hashCode", hashcode.getName());
        assertEquals(0, hashcode.getParameters().size());
        assertEquals("int", hashcode.getReturnType().getName());
        assertThat(hashcode.getBody())
                .contains("result=prime * result + ((object == null) ? 0 : object.hashCode());");
        assertThat(hashcode.getBody()).contains("result=prime * result + ((date == null) ? 0 : date.hashCode());");

    }

    private void assertEqualsForObjects(MethodSource<JavaClassSource> equals) {
        assertEquals("equals", equals.getName());
        assertEquals(1, equals.getParameters().size());
        assertThat(equals.getBody()).contains(
                "if (object != null) {\n  if (!object.equals(other.object)) {\n    return false;\n  }\n}");
        assertThat(equals.getBody())
                .contains("if (date != null) {\n  if (!date.equals(other.date)) {\n    return false;\n  }\n}");
    }

    @SuppressWarnings("deprecation")
    @Test
    public void testCreateHashCodeAndEqualsNoArgs() {
        Refactory.createHashCodeAndEquals(javaClass);

        List<MethodSource<JavaClassSource>> methods = javaClass.getMethods();
        MethodSource<JavaClassSource> equals = methods.get(0);
        MethodSource<JavaClassSource> hashcode = methods.get(1);

        assertEquals("equals", equals.getName());
        assertEquals(1, equals.getParameters().size());

        assertEquals("hashCode", hashcode.getName());
        assertEquals(0, hashcode.getParameters().size());
        assertEquals("int", hashcode.getReturnType().getName());
        assertFalse(javaClass.hasSyntaxErrors());
    }

    @Test
    public void testCreateHashCodeAndEqualsSubclass() {
        JavaClassSource subClass = Roaster.parse(JavaClassSource.class,
                "import java.util.Set;import java.util.Date; public class Foo extends Date { private int foo; private String firstName; private Set<String> names; private final int bar; }");
        FieldSource<JavaClassSource> intField = subClass.getField("foo");
        FieldSource<JavaClassSource> stringField = subClass.getField("firstName");
        Refactory.createHashCodeAndEquals(subClass, intField, stringField);

        List<MethodSource<JavaClassSource>> methods = subClass.getMethods();
        assertTrue(subClass.getMethods().size() == 2);
        MethodSource<JavaClassSource> equals = methods.get(0);
        MethodSource<JavaClassSource> hashcode = methods.get(1);
        assertHashCodeForSubclass(hashcode);
        assertEqualsForSubclass(equals);
        assertFalse(subClass.hasSyntaxErrors());
        subClass.removeMethod(equals);
        subClass.removeMethod(hashcode);
        assertTrue(subClass.getMethods().size() == 0);

        Refactory.createEquals(subClass, intField, stringField);
        methods = subClass.getMethods();
        assertTrue(subClass.getMethods().size() == 1);
        equals = methods.get(0);
        assertEqualsForSubclass(equals);
        assertFalse(subClass.hasSyntaxErrors());
        subClass.removeMethod(equals);
        assertTrue(subClass.getMethods().size() == 0);

        Refactory.createHashCode(subClass, intField, stringField);
        methods = subClass.getMethods();
        assertTrue(subClass.getMethods().size() == 1);
        hashcode = methods.get(0);
        assertEqualsForSubclass(equals);
        assertFalse(subClass.hasSyntaxErrors());
        subClass.removeMethod(hashcode);
        assertTrue(subClass.getMethods().size() == 0);
    }

    private void assertHashCodeForSubclass(MethodSource<JavaClassSource> hashcode) {
        assertEquals("hashCode", hashcode.getName());
        assertEquals(0, hashcode.getParameters().size());
        assertEquals("int", hashcode.getReturnType().getName());
        assertThat(hashcode.getBody()).contains("int result=super.hashCode();");

    }

    private void assertEqualsForSubclass(MethodSource<JavaClassSource> equals) {
        assertEquals("equals", equals.getName());
        assertEquals(1, equals.getParameters().size());
        assertThat(equals.getBody()).contains("if (!super.equals(obj)) {\n  return false;\n}");
    }

    @Test
    public void testCreateHashCodeAndEqualsOuterClass() {
        JavaClassSource outerClass = Roaster.parse(JavaClassSource.class,
                "public class Foo { private Foo.Bar bar; class Bar{ private Boolean flag; } }");
        FieldSource<JavaClassSource> outerField = outerClass.getField("bar");

        Refactory.createHashCodeAndEquals(outerClass, outerField);
        assertTrue(outerClass.getMethods().size() == 2);
        List<MethodSource<JavaClassSource>> methods = outerClass.getMethods();
        MethodSource<JavaClassSource> equals = methods.get(0);
        MethodSource<JavaClassSource> hashcode = methods.get(1);
        assertHashCodeForOuterClass(hashcode);
        assertEqualsForOuterClass(equals);
        assertFalse(outerClass.hasSyntaxErrors());
        outerClass.removeMethod(equals);
        outerClass.removeMethod(hashcode);
        assertTrue(outerClass.getMethods().size() == 0);

        Refactory.createEquals(outerClass, outerField);
        assertTrue(outerClass.getMethods().size() == 1);
        methods = outerClass.getMethods();
        equals = methods.get(0);
        assertEqualsForOuterClass(equals);
        assertFalse(outerClass.hasSyntaxErrors());
        outerClass.removeMethod(equals);
        assertTrue(outerClass.getMethods().size() == 0);

        Refactory.createHashCode(outerClass, outerField);
        assertTrue(outerClass.getMethods().size() == 1);
        methods = outerClass.getMethods();
        hashcode = methods.get(0);
        assertHashCodeForOuterClass(hashcode);
        assertFalse(outerClass.hasSyntaxErrors());
        outerClass.removeMethod(hashcode);
        assertTrue(outerClass.getMethods().size() == 0);

    }

    private void assertHashCodeForOuterClass(MethodSource<JavaClassSource> hashcode) {
        assertEquals("hashCode", hashcode.getName());
        assertEquals(0, hashcode.getParameters().size());
        assertEquals("int", hashcode.getReturnType().getName());
        assertThat(hashcode.getBody()).contains("result=prime * result + ((bar == null) ? 0 : bar.hashCode());");

    }

    private void assertEqualsForOuterClass(MethodSource<JavaClassSource> equals) {
        assertEquals("equals", equals.getName());
        assertEquals(1, equals.getParameters().size());
        assertThat(equals.getBody())
                .contains("if (bar != null) {\n  if (!bar.equals(other.bar)) {\n    return false;\n  }\n}");
    }

    @Test
    @Disabled
    // This is not supported for now
    public void testCreateHashCodeAndEqualsInnerClass() {
        JavaClassSource outerClass = Roaster.parse(JavaClassSource.class,
                "public class Foo { private Foo.Bar bar; class Bar{ private Boolean flag; } }");
        JavaClassSource innerClass = (JavaClassSource) outerClass.getNestedTypes().get(0);
        FieldSource<JavaClassSource> innerField = innerClass.getField("flag");
        Refactory.createHashCodeAndEquals(innerClass, innerField);

        List<MethodSource<JavaClassSource>> methods = innerClass.getMethods();
        assertTrue(innerClass.getMethods().size() == 2);
        MethodSource<JavaClassSource> equals = methods.get(0);
        MethodSource<JavaClassSource> hashcode = methods.get(1);
        MethodSource<JavaClassSource> outerTypeAccessor = methods.get(2);
        assertEqualsForInnerClass(equals);
        assertHashCodeForInnerClass(hashcode);
        assertEquals("getOuterType", outerTypeAccessor.getName());
        assertFalse(outerClass.hasSyntaxErrors());
        innerClass.removeMethod(equals);
        innerClass.removeMethod(hashcode);

        Refactory.createEquals(innerClass, innerField);
        methods = innerClass.getMethods();
        assertTrue(innerClass.getMethods().size() == 1);
        equals = methods.get(0);
        assertEqualsForInnerClass(equals);
        assertFalse(outerClass.hasSyntaxErrors());
        innerClass.removeMethod(equals);
        assertTrue(innerClass.getMethods().size() == 0);

        Refactory.createHashCode(innerClass, innerField);
        methods = innerClass.getMethods();
        assertTrue(innerClass.getMethods().size() == 1);
        hashcode = methods.get(0);
        assertHashCodeForInnerClass(hashcode);
        assertFalse(outerClass.hasSyntaxErrors());
        innerClass.removeMethod(hashcode);
        assertTrue(innerClass.getMethods().size() == 0);
    }

    private void assertHashCodeForInnerClass(MethodSource<JavaClassSource> hashcode) {
        assertEquals("hashCode", hashcode.getName());
        assertEquals(0, hashcode.getParameters().size());
        assertEquals("int", hashcode.getReturnType().getName());
        assertThat(hashcode.getBody()).contains("result=prime * result + getOuterType().hashCode();");
        assertThat(hashcode.getBody()).contains("result=prime * result + ((flag == null) ? 0 : flag.hashCode());");

    }

    private void assertEqualsForInnerClass(MethodSource<JavaClassSource> equals) {
        assertEquals("equals", equals.getName());
        assertEquals(1, equals.getParameters().size());
        assertThat(equals.getBody())
                .contains("if ((!getOuterType().equals(other.getOuterType()))) {\n  return false;\n}");
        assertThat(equals.getBody())
                .contains("if (flag != null) {\n  if (!flag.equals(other.flag)) {\n    return false;\n  }\n}");

    }

    @Test
    public void testCreateHashCodeAndEqualsMultipleLongFields() {
        JavaClassSource aClass = Roaster.parse(JavaClassSource.class,
                "public class Foo { private double firstDouble; private double secondDouble;}");
        FieldSource<JavaClassSource> firstLongField = aClass.getField("firstDouble");
        FieldSource<JavaClassSource> secondLongField = aClass.getField("secondDouble");

        Refactory.createHashCodeAndEquals(aClass, firstLongField, secondLongField);
        List<MethodSource<JavaClassSource>> methods = aClass.getMethods();
        assertEquals(2, aClass.getMethods().size());
        MethodSource<JavaClassSource> equals = methods.get(0);
        MethodSource<JavaClassSource> hashcode = methods.get(1);
        assertHashCodeForMultipleLongFields(hashcode);
        assertEqualsForMultipleLongFields(equals);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        aClass.removeMethod(hashcode);
        assertEquals(0, aClass.getMethods().size());

        Refactory.createEquals(aClass, firstLongField, secondLongField);
        methods = aClass.getMethods();
        assertEquals(1, aClass.getMethods().size());
        equals = methods.get(0);
        assertEqualsForMultipleLongFields(equals);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(equals);
        assertEquals(0, aClass.getMethods().size());

        Refactory.createHashCode(aClass, firstLongField, secondLongField);
        methods = aClass.getMethods();
        assertEquals(1, aClass.getMethods().size());
        hashcode = methods.get(0);
        assertHashCodeForMultipleLongFields(hashcode);
        assertFalse(aClass.hasSyntaxErrors());
        aClass.removeMethod(hashcode);
        assertEquals(0, aClass.getMethods().size());

    }

    private void assertHashCodeForMultipleLongFields(MethodSource<JavaClassSource> hashcode) {
        assertEquals("hashCode", hashcode.getName());
        assertEquals(0, hashcode.getParameters().size());
        assertEquals("int", hashcode.getReturnType().getName());
        assertThat(hashcode.getBody()).contains("long temp;");
        assertEquals(1, StringUtils.countMatches(hashcode.getBody(), "long temp;"));
        assertThat(hashcode.getBody()).contains("temp=Double.doubleToLongBits(firstDouble);");
        assertThat(hashcode.getBody()).contains("temp=Double.doubleToLongBits(secondDouble);");
        assertThat(hashcode.getBody()).contains("prime * result + (int)(temp ^ (temp >>> 32));");
        assertEquals(2,
                StringUtils.countMatches(hashcode.getBody(), "prime * result + (int)(temp ^ (temp >>> 32));"));
    }

    private void assertEqualsForMultipleLongFields(MethodSource<JavaClassSource> equals) {
        assertEquals("equals", equals.getName());
        assertEquals(1, equals.getParameters().size());
        assertThat(equals.getBody()).contains(
                "if (Double.doubleToLongBits(firstDouble) != Double.doubleToLongBits(other.firstDouble)) {\n  return false;\n}");
        assertThat(equals.getBody()).contains(
                "if (Double.doubleToLongBits(secondDouble) != Double.doubleToLongBits(other.secondDouble)) {\n  return false;\n}");
    }
}