Skip to content

Commit

Permalink
Test and fix for #202
Browse files Browse the repository at this point in the history
  • Loading branch information
christophercurrie committed Apr 16, 2015
1 parent 9e581bb commit c2342fd
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ object BeanIntrospector {

def isNotSyntheticOrBridge(m: Method): Boolean = !(m.isBridge || m.isSynthetic)

def findMethod(cls: Class[_], name: String): Option[Method] =
listMethods(cls).filter(isNotSyntheticOrBridge).find(m => NameTransformer.decode(m.getName) == name).headOption
def findMethod(cls: Class[_], name: String): Seq[Method] =
listMethods(cls).filter(isNotSyntheticOrBridge).filter(m => NameTransformer.decode(m.getName) == name)

def listFields(cls: Class[_]): Stream[Field] = cls match {
case null => Stream.empty
Expand All @@ -109,11 +109,11 @@ object BeanIntrospector {
}

def findGetter(cls: Class[_], propertyName: String): Option[Method] = {
findMethod(cls, propertyName).filter(isAcceptableGetter)
findMethod(cls, propertyName).find(isAcceptableGetter)
}

def findBeanGetter(cls: Class[_], propertyName: String): Option[Method] = {
findMethod(cls, "get" + propertyName.capitalize).filter(isAcceptableGetter)
findMethod(cls, "get" + propertyName.capitalize).find(isAcceptableGetter)
}

//True if the method fits the 'getter' pattern
Expand All @@ -122,11 +122,11 @@ object BeanIntrospector {
}

def findSetter(cls: Class[_], propertyName: String): Option[Method] = {
findMethod(cls, propertyName + "_=").filter(isAcceptableSetter)
findMethod(cls, propertyName + "_=").find(isAcceptableSetter)
}

def findBeanSetter(cls: Class[_], propertyName: String): Option[Method] = {
findMethod(cls, "set" + propertyName.capitalize).filter(isAcceptableSetter)
findMethod(cls, "set" + propertyName.capitalize).find(isAcceptableSetter)
}

//True if the method fits the 'setter' pattern
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.fasterxml.jackson.module.scala.introspect

import com.fasterxml.jackson.module.scala.introspect.BeanIntrospectorTest.DecodedNameMatcher
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.{Inside, OptionValues, LoneElement, FlatSpec}
Expand All @@ -8,63 +9,76 @@ import reflect.NameTransformer
import com.fasterxml.jackson.module.scala.BaseSpec
import java.lang.reflect.Member

class PlainCtorBean(`field-name`: Int)
{
// This needs to exist otherwise it gets optimized away
def x = `field-name`
}
object BeanIntrospectorTest {

class ValCtorBean(val `field-name`: Int)
case class ValCaseBean(`field-name`: Int)
class PlainCtorBean(`field-name`: Int) {
// This needs to exist otherwise it gets optimized away
def x = `field-name`
}

class VarCtorBean(var `field-name`: Int)
case class VarCaseBean(var `field-name`: Int)
class ValCtorBean(val `field-name`: Int)

class MethodBean
{
def `field-name` = 0
def `field-name_=`(v: Int) { }
}
case class ValCaseBean(`field-name`: Int)

//adding @SerialVersionUID puts a public static final int field on the generated class
//this field should be ignored
@SerialVersionUID(8675309)
case class SerialIDBean(field: String) {
@transient val shouldBeExluded = 10
@volatile var alsoExcluded = 20
}
class VarCtorBean(var `field-name`: Int)

class StaticMethodBean extends JavaStaticMethods {
val included = "included"
}
case class VarCaseBean(var `field-name`: Int)

class Parent {
var parentValue = "parentValue"
}
class MethodBean {
def `field-name` = 0

class Child extends Parent {
var childValue = "childValue"
}
def `field-name_=`(v: Int) {}
}

//adding @SerialVersionUID puts a public static final int field on the generated class
//this field should be ignored
@SerialVersionUID(8675309)
case class SerialIDBean(field: String) {
@transient val shouldBeExluded = 10
@volatile var alsoExcluded = 20
}

class StaticMethodBean extends JavaStaticMethods {
val included = "included"
}

class Parent {
var parentValue = "parentValue"
}

case class PrivateDefaultBean(private val privateField: String = "defaultValue")

trait DecodedNameMatcher {
def decodedName(expectedValue: String) =
new HavePropertyMatcher[Member, String] {
def apply(member: Member) = {
val decodedName = NameTransformer.decode(member.getName)
HavePropertyMatchResult(
decodedName == expectedValue,
"name",
expectedValue,
decodedName
)
class Child extends Parent {
var childValue = "childValue"
}

case class PrivateDefaultBean(private val privateField: String = "defaultValue")

trait DecodedNameMatcher {
def decodedName(expectedValue: String) =
new HavePropertyMatcher[Member, String] {
def apply(member: Member) = {
val decodedName = NameTransformer.decode(member.getName)
HavePropertyMatchResult(
decodedName == expectedValue,
"name",
expectedValue,
decodedName
)
}
}
}
}

class OverloadedGetter {
var firstName: String = ""
var lastName: String = ""

def firstName(firstName: String) {}
def lastName(lastName: String) {}
}
}

@RunWith(classOf[JUnitRunner])
class BeanIntrospectorTest extends BaseSpec with Inside with LoneElement with OptionValues with DecodedNameMatcher {
import BeanIntrospectorTest._

behavior of "BeanIntrospector"

Expand Down Expand Up @@ -280,6 +294,16 @@ class BeanIntrospectorTest extends BaseSpec with Inside with LoneElement with Op
props should have size 1
props.head.name shouldBe "privateField"
}

it should "find getters among overloads" in {
type Bean = OverloadedGetter

val beanDesc = BeanIntrospector[Bean](classOf[Bean])
val props = beanDesc.properties

props should have size 2
props.forall ( _.getter.isDefined ) shouldBe true
}
}


0 comments on commit c2342fd

Please sign in to comment.