• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / javabean-tester / 2736

29 Jun 2025 11:13PM UTC coverage: 86.972% (-2.5%) from 89.452%
2736

push

github

hazendaz
Remove asm/cglib replacing logic with byte buddy in mostly compliant way to how cglib worked

269 of 319 branches covered (84.33%)

62 of 84 new or added lines in 3 files covered. (73.81%)

4 existing lines in 1 file now uncovered.

494 of 568 relevant lines covered (86.97%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.33
/src/main/java/com/codebox/bean/JavaBeanTester.java
1
/*
2
 * JavaBean Tester (https://github.com/hazendaz/javabean-tester)
3
 *
4
 * Copyright 2012-2025 Hazendaz.
5
 *
6
 * All rights reserved. This program and the accompanying materials
7
 * are made available under the terms of The Apache Software License,
8
 * Version 2.0 which accompanies this distribution, and is available at
9
 * http://www.apache.org/licenses/LICENSE-2.0.txt
10
 *
11
 * Contributors:
12
 *     CodeBox (Rob Dawson).
13
 *     Hazendaz (Jeremy Landis).
14
 */
15
package com.codebox.bean;
16

17
import java.lang.reflect.Modifier;
18

19
import net.bytebuddy.ByteBuddy;
20
import net.bytebuddy.NamingStrategy;
21
import net.bytebuddy.description.NamedElement;
22
import net.bytebuddy.description.modifier.Visibility;
23
import net.bytebuddy.description.type.TypeDescription;
24
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
25
import net.bytebuddy.implementation.HashCodeMethod;
26
import net.bytebuddy.implementation.MethodDelegation;
27
import net.bytebuddy.implementation.ToStringMethod;
28
import net.bytebuddy.implementation.bind.annotation.Argument;
29
import net.bytebuddy.implementation.bind.annotation.This;
30
import net.bytebuddy.matcher.ElementMatchers;
31

32
/**
33
 * This helper class can be used to unit test the get/set/equals/canEqual/toString/hashCode methods of JavaBean-style
34
 * Value Objects.
35
 */
36
public enum JavaBeanTester {
1✔
37

38
    // Private Usage
39
    ;
40

41
    /**
42
     * Configure JavaBeanTester using Fluent API.
43
     *
44
     * @param <T>
45
     *            the generic type
46
     * @param clazz
47
     *            the clazz
48
     *
49
     * @return A builder implementing the fluent API to configure JavaBeanTester
50
     */
51
    public static <T> JavaBeanTesterBuilder<T, ?> builder(final Class<T> clazz) {
52
        // If class is final, use Object.class for comparison needs
53
        if (Modifier.isFinal(clazz.getModifiers())) {
1✔
54
            return new JavaBeanTesterBuilder<>(clazz, Object.class);
1✔
55
        }
56

57
        // Build extension from class using byte buddy
58
        Class<? extends T> loaded = new ByteBuddy().with(new NamingStrategy.AbstractBase() {
1✔
59
            @Override
60
            protected String name(TypeDescription superClass) {
61
                return clazz.getPackageName() + ".ByteBuddyExt" + superClass.getSimpleName();
1✔
62
            }
63
        }).subclass(clazz).method(ElementMatchers.isEquals())
1✔
64
                .intercept(MethodDelegation.to(InstanceOfEqualsInterceptor.class)).method(ElementMatchers.isHashCode())
1✔
65
                .intercept(HashCodeMethod.usingSuperClassOffset()).method(ElementMatchers.isToString())
1✔
66
                .intercept(ToStringMethod.prefixedBySimpleClassName()).method(ElementMatchers.named("canEqual"))
1✔
67
                .intercept(MethodDelegation.to(CanEqualInterceptor.class))
1✔
68
                .defineField("javabeanExtension", String.class, Visibility.PACKAGE_PRIVATE).make()
1✔
69
                .load(clazz.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER).getLoaded();
1✔
70

71
        // Builder with proper extension class
72
        return builder(clazz, loaded);
1✔
73
    }
74

75
    /**
76
     * Configure JavaBeanTester using Fluent API.
77
     *
78
     * @param <T>
79
     *            the generic type
80
     * @param <E>
81
     *            the element type
82
     * @param clazz
83
     *            the clazz
84
     * @param extension
85
     *            the extension
86
     *
87
     * @return A builder implementing the fluent API to configure JavaBeanTester
88
     */
89
    public static <T, E> JavaBeanTesterBuilder<T, E> builder(final Class<T> clazz, final Class<E> extension) {
90
        return new JavaBeanTesterBuilder<>(clazz, extension);
1✔
91
    }
92

93
    /**
94
     * The Class CanEqualInterceptor.
95
     */
96
    public final static class CanEqualInterceptor {
97

98
        /**
99
         * Prevents instantiation a new can equal interceptor.
100
         */
NEW
101
        CanEqualInterceptor() {
×
102
            // Private constructor to prevent instantiation
NEW
103
        }
×
104

105
        /**
106
         * Can Equal Interceptor.
107
         *
108
         * @param object
109
         *            The object to check can equals
110
         * @return boolean of can equals
111
         */
112
        public static boolean canEqual(final Object object) {
113
            return object instanceof NamedElement.WithRuntimeName;
1✔
114
        }
115

116
    }
117

118
    /**
119
     * The Class InstanceOfEqualsInterceptor.
120
     */
121
    public final static class InstanceOfEqualsInterceptor {
122

123
        /**
124
         * Prevents instantiation a new instance of equals interceptor.
125
         */
NEW
126
        InstanceOfEqualsInterceptor() {
×
127
            // Private constructor to prevent instantiation
NEW
128
        }
×
129

130
        /**
131
         * Equals.
132
         *
133
         * @param self
134
         *            the self
135
         * @param other
136
         *            the other
137
         * @return true, if successful
138
         */
139
        public static boolean equals(@This Object self, @Argument(0) Object other) {
140
            if (self == other) {
1✔
141
                return true;
1✔
142
            }
143
            if ((other == null) || (!self.getClass().isInstance(other) && !other.getClass().isInstance(self))) {
1!
144
                return false;
1✔
145
            }
146
            return self.hashCode() == other.hashCode();
1✔
147
        }
148
    }
149

150
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc