Metaprogramming: Align with groovy version `3.0.8` and use spock testing framework

This commit is contained in:
Alex Golub 2023-01-20 12:28:29 +02:00
parent c333a3f359
commit 34c282de34
3 changed files with 121 additions and 87 deletions

View File

@ -1,18 +1,14 @@
package com.baeldung.metaprogramming package com.baeldung.metaprogramming
import groovy.transform.AutoClone import groovy.transform.*
import groovy.transform.Canonical import groovy.util.logging.Log
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import groovy.transform.TupleConstructor
import groovy.util.logging.*
@Canonical @ToString(includePackage = false, excludes = ['id'])
@TupleConstructor @TupleConstructor
@EqualsAndHashCode @EqualsAndHashCode
@ToString(includePackage=false, excludes=['id']) @Canonical
@Log @AutoClone(style = AutoCloneStyle.SIMPLE)
@AutoClone @Log
class Employee { class Employee {
long id long id
@ -30,16 +26,15 @@ class Employee {
def propertyMissing(String propertyName, propertyValue) { def propertyMissing(String propertyName, propertyValue) {
println "property '$propertyName' is not available" println "property '$propertyName' is not available"
log.info "$propertyName is not available" log.info "$propertyName is not available"
"property '$propertyName' is not available" "property '$propertyName' with value '$propertyValue' is not available"
} }
def methodMissing(String methodName, def methodArgs) { def methodMissing(String methodName, Object methodArgs) {
log.info "$methodName is not defined" log.info "$methodName is not defined"
"method '$methodName' is not defined" "method '$methodName' is not defined"
} }
def logEmp() { def logEmp() {
log.info "Employee: $lastName, $firstName is of $age years age" log.info "Employee: $lastName, $firstName is of $age years age"
} }
}
}

View File

@ -2,32 +2,31 @@ package com.baeldung.metaprogramming.extension
import com.baeldung.metaprogramming.Employee import com.baeldung.metaprogramming.Employee
import java.time.LocalDate
import java.time.Year import java.time.Year
class BasicExtensions { class BasicExtensions {
static int getYearOfBirth(Employee self) { static int getYearOfBirth(Employee self) {
return Year.now().value - self.age return Year.now().value - self.age
} }
static String capitalize(String self) { static String capitalize(String self) {
return self.substring(0, 1).toUpperCase() + self.substring(1) return self.substring(0, 1).toUpperCase() + self.substring(1)
} }
static void printCounter(Integer self) { static void printCounter(Integer self) {
while (self>0) { while (self > 0) {
println self println self
self-- self--
} }
} }
static Long square(Long self) { static Long square(Long self) {
return self*self return self * self
} }
static BigDecimal cube(BigDecimal self) { static BigDecimal cube(BigDecimal self) {
return self*self*self return self * self * self
} }
} }

View File

@ -1,123 +1,163 @@
package com.baeldung.metaprogramming package com.baeldung.metaprogramming
import spock.lang.Specification
import java.time.LocalDate
import java.time.Period
import java.time.Year import java.time.Year
class MetaprogrammingUnitTest extends GroovyTestCase { class MetaprogrammingUnitTest extends Specification {
Employee emp = new Employee(firstName: "Norman", lastName: "Lewis") Employee emp
void testPropertyMissing() { void setup() {
assert emp.address == "property 'address' is not available" emp = new Employee(firstName: "Norman", lastName: "Lewis")
} }
void testMethodMissing() { def "testPropertyMissing"() {
expect:
emp.address == "property 'address' is not available"
}
def "testMethodMissing"() {
given:
Employee emp = new Employee() Employee emp = new Employee()
try {
emp.getFullName() expect:
} catch(MissingMethodException e) { emp.getFullName() == "method 'getFullName' is not defined"
println "method is not defined"
}
assert emp.getFullName() == "method 'getFullName' is not defined"
} }
void testMetaClassProperty() { def "testMetaClassProperty"() {
when:
Employee.metaClass.address = "" Employee.metaClass.address = ""
emp = new Employee(firstName: "Norman", lastName: "Lewis", address: "US")
assert emp.address == "US" and:
emp = new Employee(firstName: "Norman",
lastName: "Lewis",
address: "US")
then:
emp.address == "US"
} }
void testMetaClassMethod() { def "testMetaClassMethod"() {
when:
emp.metaClass.getFullName = { emp.metaClass.getFullName = {
"$lastName, $firstName" "$lastName, $firstName"
} }
assert emp.getFullName() == "Lewis, Norman"
then:
emp.getFullName() == "Lewis, Norman"
} }
void testMetaClassConstructor() { def "testOnlyNameConstructor"() {
try { when:
Employee emp = new Employee("Norman") new Employee("Norman")
} catch(GroovyRuntimeException e) {
assert e.message == "Could not find matching constructor for: com.baeldung.metaprogramming.Employee(String)"
}
then:
thrown(GroovyRuntimeException)
}
def "testMetaClassConstructor"() {
when:
Employee.metaClass.constructor = { String firstName -> Employee.metaClass.constructor = { String firstName ->
new Employee(firstName: firstName) new Employee(firstName: firstName)
} }
and:
Employee norman = new Employee("Norman") Employee norman = new Employee("Norman")
assert norman.firstName == "Norman"
assert norman.lastName == null then:
norman.firstName == "Norman"
norman.lastName == null
} }
void testJavaMetaClass() { def "testJavaMetaClass"() {
when:
String.metaClass.capitalize = { String str -> String.metaClass.capitalize = { String str ->
str.substring(0, 1).toUpperCase() + str.substring(1) str.substring(0, 1).toUpperCase() + str.substring(1)
} }
assert "norman".capitalize() == "Norman"
and:
String.metaClass.static.joinWith = { String delimiter, String... args ->
String.join(delimiter, args)
}
then:
"norman".capitalize() == "Norman"
String.joinWith(" -> ", "a", "b", "c") == "a -> b -> c"
} }
void testEmployeeExtension() { def "testEmployeeExtension"() {
given:
def age = 28 def age = 28
def expectedYearOfBirth = Year.now() - age def expectedYearOfBirth = Year.now() - age
Employee emp = new Employee(age: age) Employee emp = new Employee(age: age)
assert emp.getYearOfBirth() == expectedYearOfBirth.value
expect:
emp.getYearOfBirth() == expectedYearOfBirth.value
} }
void testJavaClassesExtensions() { def "testJavaClassesExtensions"() {
when:
5.printCounter() 5.printCounter()
assert 40l.square() == 1600l then:
40L.square() == 1600L
assert (2.98).cube() == 26.463592 (2.98).cube() == 26.463592
} }
void testStaticEmployeeExtension() { def "testStaticEmployeeExtension"() {
assert Employee.getDefaultObj().firstName == "firstName" assert Employee.getDefaultObj().firstName == "firstName"
assert Employee.getDefaultObj().lastName == "lastName" assert Employee.getDefaultObj().lastName == "lastName"
assert Employee.getDefaultObj().age == 20 assert Employee.getDefaultObj().age == 20
} }
void testToStringAnnotation() { def "testToStringAnnotation"() {
Employee employee = new Employee() when:
employee.id = 1 Employee employee = new Employee().tap {
employee.firstName = "norman" id = 1
employee.lastName = "lewis" firstName = "norman"
employee.age = 28 lastName = "lewis"
age = 28
}
assert employee.toString() == "Employee(norman, lewis, 28)" then:
employee.toString() == "Employee(norman, lewis, 28)"
} }
void testTupleConstructorAnnotation() { def "testTupleConstructorAnnotation"() {
when:
Employee norman = new Employee(1, "norman", "lewis", 28) Employee norman = new Employee(1, "norman", "lewis", 28)
assert norman.toString() == "Employee(norman, lewis, 28)"
Employee snape = new Employee(2, "snape") Employee snape = new Employee(2, "snape")
assert snape.toString() == "Employee(snape, null, 0)"
then:
norman.toString() == "Employee(norman, lewis, 28)"
snape.toString() == "Employee(snape, null, 0)"
} }
void testEqualsAndHashCodeAnnotation() { def "testEqualsAndHashCodeAnnotation"() {
when:
Employee norman = new Employee(1, "norman", "lewis", 28) Employee norman = new Employee(1, "norman", "lewis", 28)
Employee normanCopy = new Employee(1, "norman", "lewis", 28) Employee normanCopy = new Employee(1, "norman", "lewis", 28)
assert norman.equals(normanCopy)
assert norman.hashCode() == normanCopy.hashCode() then:
} norman == normanCopy
norman.hashCode() == normanCopy.hashCode()
void testAutoCloneAnnotation() {
try {
Employee norman = new Employee(1, "norman", "lewis", 28)
def normanCopy = norman.clone()
assert norman == normanCopy
} catch(CloneNotSupportedException e) {
e.printStackTrace()
}
} }
void testLoggingAnnotation() { def "testAutoCloneAnnotation"() {
given:
Employee norman = new Employee(1, "norman", "lewis", 28)
when:
def normanCopy = norman.clone()
then:
norman == normanCopy
}
def "testLoggingAnnotation"() {
given:
Employee employee = new Employee(1, "Norman", "Lewis", 28) Employee employee = new Employee(1, "Norman", "Lewis", 28)
employee.logEmp() employee.logEmp() // INFO: Employee: Lewis, Norman is of 28 years age
} }
} }