Skip to content

Commit

Permalink
Add support javaGetter for is prefix boolean property (#1072)
Browse files Browse the repository at this point in the history
  • Loading branch information
seongahjo authored Nov 2, 2024
1 parent 8bb16c2 commit 5866364
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Fixture Monkey
*
* Copyright (c) 2021-present NAVER Corp.
*
* 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 com.navercorp.fixturemonkey.api.experimental;

import javax.annotation.Nullable;

import com.navercorp.fixturemonkey.api.type.TypeCache;

public final class JavaGetterPropertyFieldNameResolver {
private static final String GET_PREFIX = "get";
private static final String IS_PREFIX = "is";

@Nullable
public String resolveFieldName(Class<?> targetClass, String methodName) {
if (hasPrefix(GET_PREFIX, methodName)) {
return stripPrefixPropertyName(targetClass, methodName, GET_PREFIX.length());
} else if (hasPrefix(IS_PREFIX, methodName)) {
return stripPrefixPropertyName(targetClass, methodName, IS_PREFIX.length());
} else if (isValidField(targetClass, methodName)) {
// class could be using property-style getters (e.g. java record)
return methodName;
}

return null;
}

private static String stripPrefixPropertyName(Class<?> targetClass, String methodName, int prefixLength) {
char[] ch = methodName.toCharArray();
ch[prefixLength] = Character.toLowerCase(ch[prefixLength]);
String fieldName = new String(ch, prefixLength, ch.length - prefixLength);
return isValidField(targetClass, fieldName) ? fieldName : null;
}

private static boolean hasPrefix(String prefix, String methodName) {
return methodName.startsWith(prefix) && methodName.length() > prefix.length();
}

private static boolean isValidField(Class<?> type, String fieldName) {
return TypeCache.getFieldsByName(type).containsKey(fieldName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
import com.navercorp.fixturemonkey.api.type.TypeCache;

abstract class JavaGetterPropertySelectors {
private static final String GET_PREFIX = "get";
private static final String IS_PREFIX = "is";
private static final JavaGetterPropertyFieldNameResolver PROPERTY_FIELD_NAME_RESOLVER =
new JavaGetterPropertyFieldNameResolver();

@SuppressWarnings("unchecked")
static <T, R> JavaGetterMethodPropertySelector<T, R> resolvePropertySelector(
Expand All @@ -59,7 +59,7 @@ static <T, R> JavaGetterMethodPropertySelector<T, R> resolvePropertySelector(
throw new IllegalArgumentException("Kotlin type could not resolve property name. type: " + targetClass);
}

String fieldName = resolveFieldName(targetClass, lambda.getImplMethodName());
String fieldName = PROPERTY_FIELD_NAME_RESOLVER.resolveFieldName(targetClass, lambda.getImplMethodName());
Property fieldProperty = resolveFieldProperty(targetClass, fieldName);
Property propertyDescriptorProperty = resolvePropertyDescriptorProperty(targetClass, fieldName);

Expand All @@ -86,20 +86,6 @@ static <T, R> JavaGetterMethodPropertySelector<T, R> resolvePropertySelector(

}

@Nullable
private static String resolveFieldName(Class<?> targetClass, String methodName) {
if (hasPrefix(GET_PREFIX, methodName)) {
return stripPrefixPropertyName(targetClass, methodName, GET_PREFIX.length());
} else if (hasPrefix(IS_PREFIX, methodName)) {
return stripPrefixPropertyName(targetClass, methodName, IS_PREFIX.length());
} else if (isValidField(targetClass, methodName)) {
// class could be using property-style getters (e.g. java record)
return methodName;
}

return null;
}

@Nullable
private static Property resolveFieldProperty(Class<?> targetClass, String fieldName) {
Map<String, Field> fieldsByName = TypeCache.getFieldsByName(targetClass);
Expand All @@ -119,19 +105,4 @@ private static Property resolvePropertyDescriptorProperty(Class<?> targetClass,
}
return new PropertyDescriptorProperty(propertyDescriptorsByPropertyName.get(fieldName));
}

private static String stripPrefixPropertyName(Class<?> targetClass, String methodName, int prefixLength) {
char[] ch = methodName.toCharArray();
ch[prefixLength] = Character.toLowerCase(ch[prefixLength]);
String fieldName = new String(ch, prefixLength, ch.length - prefixLength);
return isValidField(targetClass, fieldName) ? fieldName : null;
}

private static boolean hasPrefix(String prefix, String methodName) {
return methodName.startsWith(prefix) && methodName.length() > prefix.length();
}

private static boolean isValidField(Class<?> type, String fieldName) {
return TypeCache.getFieldsByName(type).containsKey(fieldName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Fixture Monkey
*
* Copyright (c) 2021-present NAVER Corp.
*
* 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 com.navercorp.fixturemonkey.api.experimental;

import javax.annotation.Nullable;

import com.navercorp.fixturemonkey.api.type.TypeCache;

public final class JavaGetterPropertyFieldNameResolver {
private static final String GET_PREFIX = "get";
private static final String IS_PREFIX = "is";

@Nullable
public String resolveFieldName(Class<?> targetClass, String methodName) {
if (targetClass.isRecord()) {
if (isValidField(targetClass, methodName)) {
return methodName;
}
}

if (hasPrefix(GET_PREFIX, methodName)) {
return stripPrefixPropertyName(targetClass, methodName, GET_PREFIX.length());
} else if (hasPrefix(IS_PREFIX, methodName)) {
return stripPrefixPropertyName(targetClass, methodName, IS_PREFIX.length());
} else if (isValidField(targetClass, methodName)) {
// class could be using property-style getters (e.g. java record)
return methodName;
}

return null;
}

private static String stripPrefixPropertyName(Class<?> targetClass, String methodName, int prefixLength) {
char[] ch = methodName.toCharArray();
ch[prefixLength] = Character.toLowerCase(ch[prefixLength]);
String fieldName = new String(ch, prefixLength, ch.length - prefixLength);
return isValidField(targetClass, fieldName) ? fieldName : null;
}

private static boolean hasPrefix(String prefix, String methodName) {
return methodName.startsWith(prefix) && methodName.length() > prefix.length();
}

private static boolean isValidField(Class<?> type, String fieldName) {
return TypeCache.getFieldsByName(type).containsKey(fieldName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@

package com.navercorp.fixturemonkey.tests.java17;

import static com.navercorp.fixturemonkey.api.experimental.JavaGetterMethodPropertySelector.javaGetter;
import static com.navercorp.fixturemonkey.tests.TestEnvironment.TEST_COUNT;
import static org.assertj.core.api.BDDAssertions.then;

import org.junit.jupiter.api.RepeatedTest;

import com.navercorp.fixturemonkey.FixtureMonkey;
import com.navercorp.fixturemonkey.api.introspector.ConstructorPropertiesArbitraryIntrospector;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.BooleanRecord;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.CompactConstructorRecord;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.ComplexContainerRecord;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.ContainerRecord;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.DateTimeRecord;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.IsPrefixBooleanRecord;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.JavaTypeRecord;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.NoArgsConstructorRecord;
import com.navercorp.fixturemonkey.tests.java17.RecordTestSpecs.TwoConstructorsRecord;
Expand Down Expand Up @@ -162,4 +165,44 @@ void fixedNoArgsConstructorRecord() {

then(actual).isNotNull();
}

@RepeatedTest(TEST_COUNT)
void setIsPrefixPrimitiveBoolean() {
boolean actual = SUT.giveMeBuilder(IsPrefixBooleanRecord.class)
.set(javaGetter(IsPrefixBooleanRecord::isPrimitive), false)
.sample()
.isPrimitive();

then(actual).isFalse();
}

@RepeatedTest(TEST_COUNT)
void setIsPrefixWrapperBoolean() {
boolean actual = SUT.giveMeBuilder(IsPrefixBooleanRecord.class)
.set(javaGetter(IsPrefixBooleanRecord::isWrapper), false)
.sample()
.isWrapper();

then(actual).isFalse();
}

@RepeatedTest(TEST_COUNT)
void setPrimitiveBoolean() {
boolean actual = SUT.giveMeBuilder(BooleanRecord.class)
.set(javaGetter(BooleanRecord::primitive), false)
.sample()
.primitive();

then(actual).isFalse();
}

@RepeatedTest(TEST_COUNT)
void setWrapperBoolean() {
boolean actual = SUT.giveMeBuilder(BooleanRecord.class)
.set(javaGetter(BooleanRecord::wrapper), false)
.sample()
.wrapper();

then(actual).isFalse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,10 @@ public String getString() {

public abstract String getString();
}

public record IsPrefixBooleanRecord(boolean isPrimitive, Boolean isWrapper) {
}

public record BooleanRecord(boolean primitive, Boolean wrapper) {
}
}

0 comments on commit 5866364

Please sign in to comment.