Merge branch 'master' into JAVA-18149

This commit is contained in:
timis1 2023-02-21 09:42:08 +02:00 committed by GitHub
commit 3fd8017f88
247 changed files with 2979 additions and 2446 deletions

3
.gitignore vendored
View File

@ -112,3 +112,6 @@ spring-boot-modules/spring-boot-properties-3/*.log
#libraries-2 #libraries-2
libraries-2/employee* libraries-2/employee*
libraries-2/src/test/resources/crawler4j/** libraries-2/src/test/resources/crawler4j/**
#web-modules/ninja
devDb*.db

View File

@ -31,7 +31,7 @@ The projects are broadly divided into 3 lists: first, second and heavy.
Next, they are segregated further on the basis of the tests that we want to execute. Next, they are segregated further on the basis of the tests that we want to execute.
Additionally, there are 2 profiles dedicated for JDK9 and above builds. Additionally, there are 2 profiles dedicated for JDK9 and above builds - **which require JDK 17**.
We also have a parents profile to build only parent modules. We also have a parents profile to build only parent modules.

View File

@ -1,4 +1,4 @@
package com.baeldung.avro.util.serealization; package com.baeldung.avro.util.serialization;
import com.baeldung.avro.util.model.AvroHttpRequest; import com.baeldung.avro.util.model.AvroHttpRequest;
import org.apache.avro.io.DatumReader; import org.apache.avro.io.DatumReader;
@ -10,11 +10,11 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
public class AvroDeSerealizer { public class AvroDeSerializer {
private static Logger logger = LoggerFactory.getLogger(AvroDeSerealizer.class); private static Logger logger = LoggerFactory.getLogger(AvroDeSerializer.class);
public AvroHttpRequest deSerealizeAvroHttpRequestJSON(byte[] data) { public AvroHttpRequest deSerializeAvroHttpRequestJSON(byte[] data) {
DatumReader<AvroHttpRequest> reader = new SpecificDatumReader<>(AvroHttpRequest.class); DatumReader<AvroHttpRequest> reader = new SpecificDatumReader<>(AvroHttpRequest.class);
Decoder decoder = null; Decoder decoder = null;
try { try {
@ -27,7 +27,7 @@ public class AvroDeSerealizer {
return null; return null;
} }
public AvroHttpRequest deSerealizeAvroHttpRequestBinary(byte[] data) { public AvroHttpRequest deSerializeAvroHttpRequestBinary(byte[] data) {
DatumReader<AvroHttpRequest> employeeReader = new SpecificDatumReader<>(AvroHttpRequest.class); DatumReader<AvroHttpRequest> employeeReader = new SpecificDatumReader<>(AvroHttpRequest.class);
Decoder decoder = DecoderFactory.get() Decoder decoder = DecoderFactory.get()
.binaryDecoder(data, null); .binaryDecoder(data, null);

View File

@ -1,4 +1,4 @@
package com.baeldung.avro.util.serealization; package com.baeldung.avro.util.serialization;
import com.baeldung.avro.util.model.AvroHttpRequest; import com.baeldung.avro.util.model.AvroHttpRequest;
import org.apache.avro.io.*; import org.apache.avro.io.*;
@ -9,11 +9,11 @@ import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
public class AvroSerealizer { public class AvroSerializer {
private static final Logger logger = LoggerFactory.getLogger(AvroSerealizer.class); private static final Logger logger = LoggerFactory.getLogger(AvroSerializer.class);
public byte[] serealizeAvroHttpRequestJSON(AvroHttpRequest request) { public byte[] serializeAvroHttpRequestJSON(AvroHttpRequest request) {
DatumWriter<AvroHttpRequest> writer = new SpecificDatumWriter<>(AvroHttpRequest.class); DatumWriter<AvroHttpRequest> writer = new SpecificDatumWriter<>(AvroHttpRequest.class);
byte[] data = new byte[0]; byte[] data = new byte[0];
ByteArrayOutputStream stream = new ByteArrayOutputStream(); ByteArrayOutputStream stream = new ByteArrayOutputStream();
@ -30,7 +30,7 @@ public class AvroSerealizer {
return data; return data;
} }
public byte[] serealizeAvroHttpRequestBinary(AvroHttpRequest request) { public byte[] serializeAvroHttpRequestBinary(AvroHttpRequest request) {
DatumWriter<AvroHttpRequest> writer = new SpecificDatumWriter<>(AvroHttpRequest.class); DatumWriter<AvroHttpRequest> writer = new SpecificDatumWriter<>(AvroHttpRequest.class);
byte[] data = new byte[0]; byte[] data = new byte[0];
ByteArrayOutputStream stream = new ByteArrayOutputStream(); ByteArrayOutputStream stream = new ByteArrayOutputStream();

View File

@ -1,4 +1,4 @@
package com.baeldung.avro.util.serealization; package com.baeldung.avro.util.serialization;
import com.baeldung.avro.util.model.Active; import com.baeldung.avro.util.model.Active;
import com.baeldung.avro.util.model.AvroHttpRequest; import com.baeldung.avro.util.model.AvroHttpRequest;
@ -13,16 +13,16 @@ import java.util.Objects;
import static org.junit.Assert.*; import static org.junit.Assert.*;
public class AvroSerealizerDeSerealizerIntegrationTest { public class AvroSerializerDeSerializerIntegrationTest {
AvroSerealizer serealizer; AvroSerializer serializer;
AvroDeSerealizer deSerealizer; AvroDeSerializer deserializer;
AvroHttpRequest request; AvroHttpRequest request;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
serealizer = new AvroSerealizer(); serializer = new AvroSerializer();
deSerealizer = new AvroDeSerealizer(); deserializer = new AvroDeSerializer();
ClientIdentifier clientIdentifier = ClientIdentifier.newBuilder() ClientIdentifier clientIdentifier = ClientIdentifier.newBuilder()
.setHostName("localhost") .setHostName("localhost")
@ -49,22 +49,22 @@ public class AvroSerealizerDeSerealizerIntegrationTest {
@Test @Test
public void WhenSerializedUsingJSONEncoder_thenObjectGetsSerialized() { public void WhenSerializedUsingJSONEncoder_thenObjectGetsSerialized() {
byte[] data = serealizer.serealizeAvroHttpRequestJSON(request); byte[] data = serializer.serializeAvroHttpRequestJSON(request);
assertTrue(Objects.nonNull(data)); assertTrue(Objects.nonNull(data));
assertTrue(data.length > 0); assertTrue(data.length > 0);
} }
@Test @Test
public void WhenSerializedUsingBinaryEncoder_thenObjectGetsSerialized() { public void WhenSerializedUsingBinaryEncoder_thenObjectGetsSerialized() {
byte[] data = serealizer.serealizeAvroHttpRequestBinary(request); byte[] data = serializer.serializeAvroHttpRequestBinary(request);
assertTrue(Objects.nonNull(data)); assertTrue(Objects.nonNull(data));
assertTrue(data.length > 0); assertTrue(data.length > 0);
} }
@Test @Test
public void WhenDeserializeUsingJSONDecoder_thenActualAndExpectedObjectsAreEqual() { public void WhenDeserializeUsingJSONDecoder_thenActualAndExpectedObjectsAreEqual() {
byte[] data = serealizer.serealizeAvroHttpRequestJSON(request); byte[] data = serializer.serializeAvroHttpRequestJSON(request);
AvroHttpRequest actualRequest = deSerealizer.deSerealizeAvroHttpRequestJSON(data); AvroHttpRequest actualRequest = deserializer.deSerializeAvroHttpRequestJSON(data);
assertEquals(actualRequest, request); assertEquals(actualRequest, request);
assertTrue(actualRequest.getRequestTime() assertTrue(actualRequest.getRequestTime()
.equals(request.getRequestTime())); .equals(request.getRequestTime()));
@ -72,8 +72,8 @@ public class AvroSerealizerDeSerealizerIntegrationTest {
@Test @Test
public void WhenDeserializeUsingBinaryecoder_thenActualAndExpectedObjectsAreEqual() { public void WhenDeserializeUsingBinaryecoder_thenActualAndExpectedObjectsAreEqual() {
byte[] data = serealizer.serealizeAvroHttpRequestBinary(request); byte[] data = serializer.serializeAvroHttpRequestBinary(request);
AvroHttpRequest actualRequest = deSerealizer.deSerealizeAvroHttpRequestBinary(data); AvroHttpRequest actualRequest = deserializer.deSerializeAvroHttpRequestBinary(data);
assertEquals(actualRequest, request); assertEquals(actualRequest, request);
assertTrue(actualRequest.getRequestTime() assertTrue(actualRequest.getRequestTime()
.equals(request.getRequestTime())); .equals(request.getRequestTime()));

View File

@ -155,8 +155,9 @@
<repositories> <repositories>
<repository> <repository>
<id>central</id> <id>maven_central</id>
<url>https://jcenter.bintray.com</url> <name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2/</url>
</repository> </repository>
</repositories> </repositories>

View File

@ -1,17 +1,17 @@
package com.baeldung.category; package com.baeldung.category
class BaeldungCategory { class BaeldungCategory {
public static String capitalize(String self) { static String capitalize(String self) {
String capitalizedStr = self; String capitalizedStr = self
if (self.size() > 0) { if (self.size() > 0) {
capitalizedStr = self.substring(0, 1).toUpperCase() + self.substring(1); capitalizedStr = self.substring(0, 1).toUpperCase() + self.substring(1)
} }
return capitalizedStr return capitalizedStr
} }
public static double toThePower(Number self, Number exponent) { static double toThePower(Number self, Number exponent) {
return Math.pow(self, exponent); return Math.pow(self, exponent)
} }
} }

View File

@ -1,17 +1,15 @@
package com.baeldung.category; package com.baeldung.category
import groovy.lang.Category
@Category(Number) @Category(Number)
class NumberCategory { class NumberCategory {
public Number cube() { Number cube() {
return this*this*this return this**3
} }
public int divideWithRoundUp(BigDecimal divisor, boolean isRoundUp) { int divideWithRoundUp(BigDecimal divisor, boolean isRoundUp) {
def mathRound = isRoundUp ? BigDecimal.ROUND_UP : BigDecimal.ROUND_DOWN def mathRound = isRoundUp ? BigDecimal.ROUND_UP : BigDecimal.ROUND_DOWN
return (int) new BigDecimal(this).divide(divisor, 0, mathRound) return (int) new BigDecimal(this).divide(divisor, 0, mathRound)
} }
} }

View File

@ -2,13 +2,18 @@ package com.baeldung.determinedatatype
class Person { class Person {
private int ageAsInt int ageAsInt
private Double ageAsDouble Double ageAsDouble
private String ageAsString String ageAsString
Person() {} Person() {}
Person(int ageAsInt) { this.ageAsInt = ageAsInt } Person(int ageAsInt) { this.ageAsInt = ageAsInt }
Person(Double ageAsDouble) { this.ageAsDouble = ageAsDouble } Person(Double ageAsDouble) { this.ageAsDouble = ageAsDouble }
Person(String ageAsString) { this.ageAsString = ageAsString } Person(String ageAsString) { this.ageAsString = ageAsString }
} }
class Student extends Person {}
class Student extends Person {
}

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
@AutoClone(style = AutoCloneStyle.SIMPLE)
@Log @Log
@AutoClone
class Employee { class Employee {
long id long id
@ -30,10 +26,10 @@ 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"
} }
@ -41,5 +37,4 @@ class Employee {
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,7 +2,6 @@ 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 {

View File

@ -1,11 +1,11 @@
package com.baeldung.category package com.baeldung.category
import groovy.time.* import groovy.time.TimeCategory
import groovy.xml.DOMBuilder
import groovy.xml.QName
import groovy.xml.dom.DOMCategory
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import groovy.xml.*
import groovy.xml.dom.*
import com.baeldung.category.BaeldungCategory
import com.baeldung.category.NumberCategory
class CategoryUnitTest extends GroovyTestCase { class CategoryUnitTest extends GroovyTestCase {
@ -97,5 +97,4 @@ class CategoryUnitTest extends GroovyTestCase {
assert 150.9.divideWithRoundUp(12.1, false) == 12 assert 150.9.divideWithRoundUp(12.1, false) == 12
} }
} }
} }

View File

@ -1,56 +1,68 @@
package com.baeldung.determinedatatype package com.baeldung.determinedatatype
import org.junit.Assert import spock.lang.Specification
import org.junit.Test
import com.baeldung.determinedatatype.Person
public class PersonTest { class PersonTest extends Specification {
@Test def "givenWhenParameterTypeIsIntegerThenReturnTrue"() {
public void givenWhenParameterTypeIsInteger_thenReturnTrue() { given:
Person personObj = new Person(10) Person personObj = new Person(10)
Assert.assertTrue(personObj.ageAsInt instanceof Integer)
expect:
personObj.ageAsInt.class == Integer
} }
@Test def "givenWhenParameterTypeIsDouble_thenReturnTrue"() {
public void givenWhenParameterTypeIsDouble_thenReturnTrue() { given:
Person personObj = new Person(10.0) Person personObj = new Person(10.0)
Assert.assertTrue((personObj.ageAsDouble).getClass() == Double)
expect:
personObj.ageAsDouble.class == Double
} }
@Test def "givenWhenParameterTypeIsString_thenReturnTrue"() {
public void givenWhenParameterTypeIsString_thenReturnTrue() { given:
Person personObj = new Person("10 years") Person personObj = new Person("10 years")
Assert.assertTrue(personObj.ageAsString.class == String)
expect:
personObj.ageAsString.class == String
} }
@Test def "givenClassName_WhenParameterIsInteger_thenReturnTrue"() {
public void givenClassName_WhenParameterIsInteger_thenReturnTrue() { expect:
Assert.assertTrue(Person.class.getDeclaredField('ageAsInt').type == int.class) Person.class.getDeclaredField('ageAsInt').type == int.class
} }
@Test def "givenWhenObjectIsInstanceOfType_thenReturnTrue"() {
public void givenWhenObjectIsInstanceOfType_thenReturnTrue() { given:
Person personObj = new Person() Person personObj = new Person()
Assert.assertTrue(personObj instanceof Person)
expect:
personObj.class == Person
} }
@Test def "givenWhenInstanceIsOfSubtype_thenReturnTrue"() {
public void givenWhenInstanceIsOfSubtype_thenReturnTrue() { given:
Student studentObj = new Student() Student studentObj = new Student()
Assert.assertTrue(studentObj in Person)
expect:
studentObj.class.superclass == Person
} }
@Test def "givenGroovyList_WhenFindClassName_thenReturnTrue"() {
public void givenGroovyList_WhenFindClassName_thenReturnTrue() { given:
def ageList = ['ageAsString', 'ageAsDouble', 10] def ageList = ['ageAsString', 'ageAsDouble', 10]
Assert.assertTrue(ageList.class == ArrayList)
Assert.assertTrue(ageList.getClass() == ArrayList) expect:
ageList.class == ArrayList
ageList.getClass() == ArrayList
} }
@Test def "givenGroovyMap_WhenFindClassName_thenReturnTrue"() {
public void givenGrooyMap_WhenFindClassName_thenReturnTrue() { given:
def ageMap = [ageAsString: '10 years', ageAsDouble: 10.0] def ageMap = [ageAsString: '10 years', ageAsDouble: 10.0]
Assert.assertFalse(ageMap.class == LinkedHashMap)
expect:
ageMap.getClass() == LinkedHashMap
} }
} }

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)
} }
void testEmployeeExtension() { then:
"norman".capitalize() == "Norman"
String.joinWith(" -> ", "a", "b", "c") == "a -> b -> c"
}
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)"
} }
void testTupleConstructorAnnotation() { then:
employee.toString() == "Employee(norman, lewis, 28)"
}
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() { def "testAutoCloneAnnotation"() {
try { given:
Employee norman = new Employee(1, "norman", "lewis", 28) Employee norman = new Employee(1, "norman", "lewis", 28)
when:
def normanCopy = norman.clone() def normanCopy = norman.clone()
assert norman == normanCopy
} catch(CloneNotSupportedException e) { then:
e.printStackTrace() norman == normanCopy
}
} }
void testLoggingAnnotation() { 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
} }
} }

View File

@ -1,48 +1,62 @@
package com.baeldung.templateengine package com.baeldung.templateengine
import groovy.text.GStringTemplateEngine
import groovy.text.SimpleTemplateEngine import groovy.text.SimpleTemplateEngine
import groovy.text.StreamingTemplateEngine import groovy.text.StreamingTemplateEngine
import groovy.text.GStringTemplateEngine
import groovy.text.XmlTemplateEngine
import groovy.text.XmlTemplateEngine import groovy.text.XmlTemplateEngine
import groovy.text.markup.MarkupTemplateEngine import groovy.text.markup.MarkupTemplateEngine
import groovy.text.markup.TemplateConfiguration import groovy.text.markup.TemplateConfiguration
import spock.lang.Specification
class TemplateEnginesUnitTest extends GroovyTestCase { class TemplateEnginesUnitTest extends Specification {
def bindMap = [user: "Norman", signature: "Baeldung"] final Map BIND_MAP = [user: "Norman", signature: "Baeldung"]
void testSimpleTemplateEngine() { def "testSimpleTemplateEngine"() {
given:
def smsTemplate = 'Dear <% print user %>, Thanks for reading our Article. ${signature}' def smsTemplate = 'Dear <% print user %>, Thanks for reading our Article. ${signature}'
def smsText = new SimpleTemplateEngine().createTemplate(smsTemplate).make(bindMap)
assert smsText.toString() == "Dear Norman, Thanks for reading our Article. Baeldung" when:
def smsText = new SimpleTemplateEngine().createTemplate(smsTemplate).make(BIND_MAP)
then:
smsText.toString() == "Dear Norman, Thanks for reading our Article. Baeldung"
} }
void testStreamingTemplateEngine() { def "testStreamingTemplateEngine"() {
given:
def articleEmailTemplate = new File('src/main/resources/articleEmail.template') def articleEmailTemplate = new File('src/main/resources/articleEmail.template')
bindMap.articleText = """1. Overview //can be a string larger than 64k
This is a tutorial article on Template Engines""" //can be a string larger than 64k BIND_MAP.articleText = """|1. Overview
|This is a tutorial article on Template Engines""".stripMargin()
def articleEmailText = new StreamingTemplateEngine().createTemplate(articleEmailTemplate).make(bindMap) when:
def articleEmailText = new StreamingTemplateEngine().createTemplate(articleEmailTemplate).make(BIND_MAP)
assert articleEmailText.toString() == """Dear Norman,
Please read the requested article below.
1. Overview
This is a tutorial article on Template Engines
From,
Baeldung"""
then:
articleEmailText.toString() == """|Dear Norman,
|Please read the requested article below.
|1. Overview
|This is a tutorial article on Template Engines
|From,
|Baeldung""".stripMargin()
} }
void testGStringTemplateEngine() { def "testGStringTemplateEngine"() {
given:
def emailTemplate = new File('src/main/resources/email.template') def emailTemplate = new File('src/main/resources/email.template')
def emailText = new GStringTemplateEngine().createTemplate(emailTemplate).make(bindMap)
assert emailText.toString() == "Dear Norman,\nThanks for subscribing our services.\nBaeldung" when:
def emailText = new GStringTemplateEngine().createTemplate(emailTemplate).make(BIND_MAP)
then:
emailText.toString() == """|Dear Norman,
|Thanks for subscribing our services.
|Baeldung""".stripMargin()
} }
void testXmlTemplateEngine() { def "testXmlTemplateEngine"() {
given:
def emailXmlTemplate = '''<xs xmlns:gsp='groovy-server-pages'> def emailXmlTemplate = '''<xs xmlns:gsp='groovy-server-pages'>
<gsp:scriptlet>def emailContent = "Thanks for subscribing our services."</gsp:scriptlet> <gsp:scriptlet>def emailContent = "Thanks for subscribing our services."</gsp:scriptlet>
<email> <email>
@ -51,11 +65,16 @@ Baeldung"""
<signature>${signature}</signature> <signature>${signature}</signature>
</email> </email>
</xs>''' </xs>'''
def emailXml = new XmlTemplateEngine().createTemplate(emailXmlTemplate).make(bindMap)
when:
def emailXml = new XmlTemplateEngine().createTemplate(emailXmlTemplate).make(BIND_MAP)
then:
println emailXml.toString() println emailXml.toString()
} }
void testMarkupTemplateEngineHtml() { def "testMarkupTemplateEngineHtml"() {
given:
def emailHtmlTemplate = """html { def emailHtmlTemplate = """html {
head { head {
title('Service Subscription Email') title('Service Subscription Email')
@ -67,13 +86,15 @@ Baeldung"""
} }
}""" }"""
when:
def emailHtml = new MarkupTemplateEngine().createTemplate(emailHtmlTemplate).make() def emailHtml = new MarkupTemplateEngine().createTemplate(emailHtmlTemplate).make()
println emailHtml.toString()
then:
println emailHtml.toString()
} }
void testMarkupTemplateEngineXml() { def "testMarkupTemplateEngineXml"() {
given:
def emailXmlTemplate = """xmlDeclaration() def emailXmlTemplate = """xmlDeclaration()
xs{ xs{
email { email {
@ -83,14 +104,18 @@ Baeldung"""
} }
} }
""" """
TemplateConfiguration config = new TemplateConfiguration() TemplateConfiguration config = new TemplateConfiguration().with {
config.autoIndent = true autoIndent = true
config.autoEscape = true autoEscape = true
config.autoNewLine = true autoNewLine = true
return it
}
when:
def emailXml = new MarkupTemplateEngine(config).createTemplate(emailXmlTemplate).make() def emailXml = new MarkupTemplateEngine(config).createTemplate(emailXmlTemplate).make()
then:
println emailXml.toString() println emailXml.toString()
} }
} }

View File

@ -113,9 +113,11 @@
<repositories> <repositories>
<repository> <repository>
<id>central</id> <id>maven_central</id>
<url>http://jcenter.bintray.com</url> <name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2/</url>
</repository> </repository>
</repositories> </repositories>
</project> </project>

View File

@ -1,58 +1,57 @@
package com.baeldung.find package com.baeldung.find
import com.baeldung.find.Person import spock.lang.Specification
import org.junit.Test
import static org.junit.Assert.* class ListFindUnitTest extends Specification {
class ListFindUnitTest { final personList = [
private final personList = [
new Person("Regina", "Fitzpatrick", 25), new Person("Regina", "Fitzpatrick", 25),
new Person("Abagail", "Ballard", 26), new Person("Abagail", "Ballard", 26),
new Person("Lucian", "Walter", 30), new Person("Lucian", "Walter", 30),
] ]
@Test def "whenListContainsElement_thenCheckReturnsTrue"() {
void whenListContainsElement_thenCheckReturnsTrue() { given:
def list = ['a', 'b', 'c'] def list = ['a', 'b', 'c']
assertTrue(list.indexOf('a') > -1) expect:
assertTrue(list.contains('a')) list.indexOf('a') > -1
list.contains('a')
} }
@Test def "whenListContainsElement_thenCheckWithMembershipOperatorReturnsTrue"() {
void whenListContainsElement_thenCheckWithMembershipOperatorReturnsTrue() { given:
def list = ['a', 'b', 'c'] def list = ['a', 'b', 'c']
assertTrue('a' in list) expect:
'a' in list
} }
@Test def "givenListOfPerson_whenUsingStreamMatching_thenShouldEvaluateList"() {
void givenListOfPerson_whenUsingStreamMatching_thenShouldEvaluateList() { expect:
assertTrue(personList.stream().anyMatch {it.age > 20}) personList.stream().anyMatch { it.age > 20 }
assertFalse(personList.stream().allMatch {it.age < 30}) !personList.stream().allMatch { it.age < 30 }
} }
@Test def "givenListOfPerson_whenUsingCollectionMatching_thenShouldEvaluateList"() {
void givenListOfPerson_whenUsingCollectionMatching_thenShouldEvaluateList() { expect:
assertTrue(personList.any {it.age > 20}) personList.any { it.age > 20 }
assertFalse(personList.every {it.age < 30}) !personList.every { it.age < 30 }
} }
@Test def "givenListOfPerson_whenUsingStreamFind_thenShouldReturnMatchingElements"() {
void givenListOfPerson_whenUsingStreamFind_thenShouldReturnMatchingElements() { expect:
assertTrue(personList.stream().filter {it.age > 20}.findAny().isPresent()) personList.stream().filter { it.age > 20 }.findAny().isPresent()
assertFalse(personList.stream().filter {it.age > 30}.findAny().isPresent()) !personList.stream().filter { it.age > 30 }.findAny().isPresent()
assertTrue(personList.stream().filter {it.age > 20}.findAll().size() == 3) personList.stream().filter { it.age > 20 }.findAll().size() == 3
assertTrue(personList.stream().filter {it.age > 30}.findAll().isEmpty()) personList.stream().filter { it.age > 30 }.findAll().isEmpty()
} }
@Test def "givenListOfPerson_whenUsingCollectionFind_thenShouldReturnMatchingElements"() {
void givenListOfPerson_whenUsingCollectionFind_thenShouldReturnMatchingElements() { expect:
assertNotNull(personList.find {it.age > 20}) personList.find { it.age > 20 } == new Person("Regina", "Fitzpatrick", 25)
assertNull(personList.find {it.age > 30}) personList.find { it.age > 30 } == null
assertTrue(personList.findAll {it.age > 20}.size() == 3) personList.findAll { it.age > 20 }.size() == 3
assertTrue(personList.findAll {it.age > 30}.isEmpty()) personList.findAll { it.age > 30 }.isEmpty()
} }
} }

View File

@ -1,76 +1,81 @@
package com.baeldung.find package com.baeldung.find
import com.baeldung.find.Person import spock.lang.Specification
import org.junit.Test
import static org.junit.Assert.* class MapFindUnitTest extends Specification {
class MapFindUnitTest { final personMap = [
private final personMap = [
Regina: new Person("Regina", "Fitzpatrick", 25), Regina: new Person("Regina", "Fitzpatrick", 25),
Abagail: new Person("Abagail", "Ballard", 26), Abagail: new Person("Abagail", "Ballard", 26),
Lucian: new Person("Lucian", "Walter", 30) Lucian: new Person("Lucian", "Walter", 30)
] ]
@Test def "whenMapContainsKeyElement_thenCheckReturnsTrue"() {
void whenMapContainsKeyElement_thenCheckReturnsTrue() { given:
def map = [a: 'd', b: 'e', c: 'f'] def map = [a: 'd', b: 'e', c: 'f']
assertTrue(map.containsKey('a')) expect:
assertFalse(map.containsKey('e')) map.containsKey('a')
assertTrue(map.containsValue('e')) !map.containsKey('e')
map.containsValue('e')
} }
@Test def "whenMapContainsKeyElement_thenCheckByMembershipReturnsTrue"() {
void whenMapContainsKeyElement_thenCheckByMembershipReturnsTrue() { given:
def map = [a: 'd', b: 'e', c: 'f'] def map = [a: 'd', b: 'e', c: 'f']
assertTrue('a' in map) expect:
assertFalse('f' in map) 'a' in map
'f' !in map
} }
@Test def "whenMapContainsFalseBooleanValues_thenCheckReturnsFalse"() {
void whenMapContainsFalseBooleanValues_thenCheckReturnsFalse() { given:
def map = [a: true, b: false, c: null] def map = [a: true, b: false, c: null]
assertTrue(map.containsKey('b')) expect:
assertTrue('a' in map) map.containsKey('b')
assertFalse('b' in map) 'a' in map
assertFalse('c' in map) 'b' !in map // get value of key 'b' and does the assertion
'c' !in map
} }
@Test def "givenMapOfPerson_whenUsingStreamMatching_thenShouldEvaluateMap"() {
void givenMapOfPerson_whenUsingStreamMatching_thenShouldEvaluateMap() { expect:
assertTrue(personMap.keySet().stream().anyMatch {it == "Regina"}) personMap.keySet().stream()
assertFalse(personMap.keySet().stream().allMatch {it == "Albert"}) .anyMatch { it == "Regina" }
assertFalse(personMap.values().stream().allMatch {it.age < 30}) !personMap.keySet().stream()
assertTrue(personMap.entrySet().stream().anyMatch {it.key == "Abagail" && it.value.lastname == "Ballard"}) .allMatch { it == "Albert" }
!personMap.values().stream()
.allMatch { it.age < 30 }
personMap.entrySet().stream()
.anyMatch { it.key == "Abagail" && it.value.lastname == "Ballard" }
} }
@Test def "givenMapOfPerson_whenUsingCollectionMatching_thenShouldEvaluateMap"() {
void givenMapOfPerson_whenUsingCollectionMatching_thenShouldEvaluateMap() { expect:
assertTrue(personMap.keySet().any {it == "Regina"}) personMap.keySet().any { it == "Regina" }
assertFalse(personMap.keySet().every {it == "Albert"}) !personMap.keySet().every { it == "Albert" }
assertFalse(personMap.values().every {it.age < 30}) !personMap.values().every { it.age < 30 }
assertTrue(personMap.any {firstname, person -> firstname == "Abagail" && person.lastname == "Ballard"}) personMap.any { firstname, person -> firstname == "Abagail" && person.lastname == "Ballard" }
} }
@Test def "givenMapOfPerson_whenUsingCollectionFind_thenShouldReturnElements"() {
void givenMapOfPerson_whenUsingCollectionFind_thenShouldReturnElements() { expect:
assertNotNull(personMap.find {it.key == "Abagail" && it.value.lastname == "Ballard"}) personMap.find { it.key == "Abagail" && it.value.lastname == "Ballard" }
assertTrue(personMap.findAll {it.value.age > 20}.size() == 3) personMap.findAll { it.value.age > 20 }.size() == 3
} }
@Test def "givenMapOfPerson_whenUsingStreamFind_thenShouldReturnElements"() {
void givenMapOfPerson_whenUsingStreamFind_thenShouldReturnElements() { expect:
assertTrue(
personMap.entrySet().stream() personMap.entrySet().stream()
.filter { it.key == "Abagail" && it.value.lastname == "Ballard" } .filter { it.key == "Abagail" && it.value.lastname == "Ballard" }
.findAny().isPresent()) .findAny()
assertTrue( .isPresent()
personMap.entrySet().stream() personMap.entrySet().stream()
.filter { it.value.age > 20 } .filter { it.value.age > 20 }
.findAll().size() == 3) .findAll()
.size() == 3
} }
} }

View File

@ -1,37 +1,10 @@
package com.baeldung.find package com.baeldung.find
import groovy.transform.Canonical
@Canonical
class Person { class Person {
private String firstname String firstname
private String lastname String lastname
private Integer age Integer age
Person(String firstname, String lastname, Integer age) {
this.firstname = firstname
this.lastname = lastname
this.age = age
}
String getFirstname() {
return firstname
}
void setFirstname(String firstname) {
this.firstname = firstname
}
String getLastname() {
return lastname
}
void setLastname(String lastname) {
this.lastname = lastname
}
Integer getAge() {
return age
}
void setAge(Integer age) {
this.age = age
}
} }

View File

@ -1,16 +1,15 @@
package com.baeldung.find package com.baeldung.find
import org.junit.Test import spock.lang.Specification
import static org.junit.Assert.assertTrue class SetFindUnitTest extends Specification {
class SetFindUnitTest { def "whenSetContainsElement_thenCheckReturnsTrue"() {
given:
@Test
void whenSetContainsElement_thenCheckReturnsTrue() {
def set = ['a', 'b', 'c'] as Set def set = ['a', 'b', 'c'] as Set
assertTrue(set.contains('a')) expect:
assertTrue('a' in set) set.contains('a')
'a' in set
} }
} }

View File

@ -1,85 +1,54 @@
package com.baeldung.iteratemap package com.baeldung.iteratemap
import com.baeldung.find.Person import spock.lang.Specification
import org.junit.Test
import static org.junit.Assert.* class IterateMapUnitTest extends Specification {
class IterateMapUnitTest { final Map map = [
@Test
void whenUsingEach_thenMapIsIterated() {
def map = [
'FF0000': 'Red', 'FF0000': 'Red',
'00FF00': 'Lime', '00FF00': 'Lime',
'0000FF': 'Blue', '0000FF': 'Blue',
'FFFF00' : 'Yellow' 'FFFF00': 'Yellow',
]
map.each { println "Hex Code: $it.key = Color Name: $it.value" }
}
@Test
void whenUsingEachWithEntry_thenMapIsIterated() {
def map = [
'E6E6FA': 'Lavender', 'E6E6FA': 'Lavender',
'D8BFD8': 'Thistle', 'D8BFD8': 'Thistle',
'DDA0DD': 'Plum', 'DDA0DD': 'Plum',
] ]
def "whenUsingEach_thenMapIsIterated"() {
expect:
map.each { println "Hex Code: $it.key = Color Name: $it.value" }
}
def "whenUsingEachWithEntry_thenMapIsIterated"() {
expect:
map.each { entry -> println "Hex Code: $entry.key = Color Name: $entry.value" } map.each { entry -> println "Hex Code: $entry.key = Color Name: $entry.value" }
} }
@Test def "whenUsingEachWithKeyAndValue_thenMapIsIterated"() {
void whenUsingEachWithKeyAndValue_thenMapIsIterated() { expect:
def map = [
'000000' : 'Black',
'FFFFFF' : 'White',
'808080' : 'Gray'
]
map.each { key, val -> map.each { key, val ->
println "Hex Code: $key = Color Name $val" println "Hex Code: $key = Color Name $val"
} }
} }
@Test def "whenUsingEachWithIndexAndEntry_thenMapIsIterated"() {
void whenUsingEachWithIndexAndEntry_thenMapIsIterated() { expect:
def map = [
'800080' : 'Purple',
'4B0082' : 'Indigo',
'6A5ACD' : 'Slate Blue'
]
map.eachWithIndex { entry, index -> map.eachWithIndex { entry, index ->
def indent = ((index == 0 || index % 2 == 0) ? " " : "") def indent = index % 2 == 0 ? " " : ""
println "$indent Hex Code: $entry.key = Color Name: $entry.value" println "$indent Hex Code: $entry.key = Color Name: $entry.value"
} }
} }
@Test def "whenUsingEachWithIndexAndKeyAndValue_thenMapIsIterated"() {
void whenUsingEachWithIndexAndKeyAndValue_thenMapIsIterated() { expect:
def map = [
'FFA07A' : 'Light Salmon',
'FF7F50' : 'Coral',
'FF6347' : 'Tomato',
'FF4500' : 'Orange Red'
]
map.eachWithIndex { key, val, index -> map.eachWithIndex { key, val, index ->
def indent = ((index == 0 || index % 2 == 0) ? " " : "") def indent = index % 2 == 0 ? " " : ""
println "$indent Hex Code: $key = Color Name: $val" println "$indent Hex Code: $key = Color Name: $val"
} }
} }
@Test def "whenUsingForLoop_thenMapIsIterated"() {
void whenUsingForLoop_thenMapIsIterated() { expect:
def map = [
'2E8B57' : 'Seagreen',
'228B22' : 'Forest Green',
'008000' : 'Green'
]
for (entry in map) { for (entry in map) {
println "Hex Code: $entry.key = Color Name: $entry.value" println "Hex Code: $entry.key = Color Name: $entry.value"
} }

View File

@ -1,173 +1,171 @@
package com.baeldung.lists package com.baeldung.lists
import static groovy.test.GroovyAssert.* import spock.lang.Specification
import org.junit.Test
class ListUnitTest { class ListUnitTest extends Specification {
@Test
void testCreateList() {
def "testCreateList"() {
when:
def list = [1, 2, 3] def list = [1, 2, 3]
assertNotNull(list)
def listMix = ['A', "b", 1, true] def listMix = ['A', "b", 1, true]
assertTrue(listMix == ['A', "b", 1, true])
def linkedList = [1, 2, 3] as LinkedList def linkedList = [1, 2, 3] as LinkedList
assertTrue(linkedList instanceof LinkedList)
ArrayList arrList = [1, 2, 3] ArrayList arrList = [1, 2, 3]
assertTrue(arrList.class == ArrayList)
def copyList = new ArrayList(arrList) def copyList = new ArrayList(arrList)
assertTrue(copyList == arrList)
def cloneList = arrList.clone() def cloneList = arrList.clone()
assertTrue(cloneList == arrList)
then:
list
listMix == ['A', "b", 1, true]
linkedList instanceof LinkedList
arrList.class == ArrayList
copyList == arrList
cloneList == arrList
} }
@Test def "testCreateEmptyList"() {
void testCreateEmptyList() { when:
def emptyList = [] def emptyList = []
assertTrue(emptyList.size() == 0)
then:
emptyList.isEmpty()
} }
@Test def "testCompareTwoLists"() {
void testCompareTwoLists() { when:
def list1 = [5, 6.0, 'p'] def list1 = [5, 6.0, 'p']
def list2 = [5, 6.0, 'p'] def list2 = [5, 6.0, 'p']
assertTrue(list1 == list2)
then:
list1 == list2
} }
@Test def "testGetItemsFromList"() {
void testGetItemsFromList(){ when:
def list = ["Hello", "World"] def list = ["Hello", "World"]
assertTrue(list.get(1) == "World") then:
assertTrue(list[1] == "World") list.get(1) == "World"
assertTrue(list[-1] == "World") list[1] == "World"
assertTrue(list.getAt(1) == "World") list[-1] == "World"
assertTrue(list.getAt(-2) == "Hello") list.getAt(1) == "World"
list.getAt(-2) == "Hello"
} }
@Test def "testAddItemsToList"() {
void testAddItemsToList() { given:
def list1 = []
def list2 = []
def list3 = [1, 2]
def list = [] when:
list1 << 1 // [1]
list1.add("Apple") // [1, "Apple"]
list << 1 list2[2] = "Box" // [null, "Box"]
list.add("Apple") list2[4] = true // [null, "Box", null, true]
assertTrue(list == [1, "Apple"])
list[2] = "Box" list1.add(1, 6.0) // [1, 6.0, "Apple"]
list[4] = true list1 += list3 // [1, 6.0, "Apple", 1, 2]
assertTrue(list == [1, "Apple", "Box", null, true]) list1 += 12 // [1, 6.0, "Apple", 1, 2, 12]
list.add(1, 6.0) then:
assertTrue(list == [1, 6.0, "Apple", "Box", null, true]) list1 == [1, 6.0, "Apple", 1, 2, 12]
list2 == [null, null, "Box", null, true]
def list2 = [1, 2]
list += list2
list += 12
assertTrue(list == [1, 6.0, "Apple", "Box", null, true, 1, 2, 12])
} }
@Test def "testUpdateItemsInList"() {
void testUpdateItemsInList() { given:
def list = [1, "Apple", 80, "App"] def list = [1, "Apple", 80, "App"]
when:
list[1] = "Box" list[1] = "Box"
list.set(2, 90) list.set(2, 90)
assertTrue(list == [1, "Box", 90, "App"])
then:
list == [1, "Box", 90, "App"]
} }
@Test def "testRemoveItemsFromList"() {
void testRemoveItemsFromList(){ given:
def list = [1, 2, 3, 4, 5, 5, 6, 6, 7] def list = [1, 2, 3, 4, 5, 5, 6, 6, 7]
list.remove(3) when:
assertTrue(list == [1, 2, 3, 5, 5, 6, 6, 7]) list.remove(3) // [1, 2, 3, 5, 5, 6, 6, 7]
list.removeElement(5) // [1, 2, 3, 5, 6, 6, 7]
list = list - 6 // [1, 2, 3, 5, 7]
list.removeElement(5) then:
assertTrue(list == [1, 2, 3, 5, 6, 6, 7]) list == [1, 2, 3, 5, 7]
assertTrue(list - 6 == [1, 2, 3, 5, 7])
} }
@Test def "testIteratingOnAList"() {
void testIteratingOnAList(){ given:
def list = [1, "App", 3, 4] def list = [1, "App", 3, 4]
list.each{ println it * 2}
expect:
list.each { println it * 2 }
list.eachWithIndex { it, i -> println "$i : $it" } list.eachWithIndex { it, i -> println "$i : $it" }
} }
@Test def "testCollectingToAnotherList"() {
void testCollectingToAnotherList(){ given:
def list = ["Kay", "Henry", "Justin", "Tom"] def list = ["Kay", "Henry", "Justin", "Tom"]
assertTrue(list.collect{"Hi " + it} == ["Hi Kay", "Hi Henry", "Hi Justin", "Hi Tom"])
when:
def collect = list.collect { "Hi " + it }
then:
collect == ["Hi Kay", "Hi Henry", "Hi Justin", "Hi Tom"]
} }
@Test def "testJoinItemsInAList"() {
void testJoinItemsInAList(){ expect:
assertTrue(["One", "Two", "Three"].join(",") == "One,Two,Three") ["One", "Two", "Three"].join(",") == "One,Two,Three"
} }
@Test def "testFilteringOnLists"() {
void testFilteringOnLists(){ given:
def filterList = [2, 1, 3, 4, 5, 6, 76] def filterList = [2, 1, 3, 4, 5, 6, 76]
assertTrue(filterList.find{it > 3} == 4)
assertTrue(filterList.findAll{it > 3} == [4, 5, 6, 76])
assertTrue(filterList.findAll{ it instanceof Number} == [2, 1, 3, 4, 5, 6, 76])
assertTrue(filterList.grep( Number )== [2, 1, 3, 4, 5, 6, 76])
assertTrue(filterList.grep{ it> 6 }== [76])
def conditionList = [2, 1, 3, 4, 5, 6, 76] def conditionList = [2, 1, 3, 4, 5, 6, 76]
assertFalse(conditionList.every{ it < 6}) expect:
filterList.find { it > 3 } == 4
assertTrue(conditionList.any{ it%2 == 0}) filterList.findAll { it > 3 } == [4, 5, 6, 76]
filterList.findAll { it instanceof Number } == [2, 1, 3, 4, 5, 6, 76]
filterList.grep(Number) == [2, 1, 3, 4, 5, 6, 76]
filterList.grep { it > 6 } == [76]
!(conditionList.every { it < 6 })
conditionList.any { it % 2 == 0 }
} }
@Test def "testGetUniqueItemsInAList"() {
void testGetUniqueItemsInAList(){ given:
assertTrue([1, 3, 3, 4].toUnique() == [1, 3, 4])
def uniqueList = [1, 3, 3, 4] def uniqueList = [1, 3, 3, 4]
uniqueList.unique()
assertTrue(uniqueList == [1, 3, 4])
assertTrue(["A", "B", "Ba", "Bat", "Cat"].toUnique{ it.size()} == ["A", "Ba", "Bat"]) when:
uniqueList.unique(true)
then:
[1, 3, 3, 4].toUnique() == [1, 3, 4]
uniqueList == [1, 3, 4]
["A", "B", "Ba", "Bat", "Cat"].toUnique { it.size() } == ["A", "Ba", "Bat"]
} }
@Test def "testSorting"() {
void testSorting(){ given:
Comparator naturalOrder = { a, b -> a == b ? 0 : a < b ? -1 : 1 }
assertTrue([1, 2, 1, 0].sort() == [0, 1, 1, 2])
Comparator mc = {a,b -> a == b? 0: a < b? 1 : -1}
def list = [1, 2, 1, 0] def list = [1, 2, 1, 0]
list.sort(mc)
assertTrue(list == [2, 1, 1, 0])
def strList = ["na", "ppp", "as"] def strList = ["na", "ppp", "as"]
assertTrue(strList.max() == "ppp")
Comparator minc = {a,b -> a == b? 0: a < b? -1 : 1}
def numberList = [3, 2, 0, 7] def numberList = [3, 2, 0, 7]
assertTrue(numberList.min(minc) == 0)
when:
list.sort(naturalOrder.reversed())
then:
list == [2, 1, 1, 0]
strList.max() == "ppp"
[1, 2, 1, 0].sort() == [0, 1, 1, 2]
numberList.min(naturalOrder) == 0
} }
} }

View File

@ -1,148 +1,160 @@
package com.baeldung.maps; package com.baeldung.maps
import static groovy.test.GroovyAssert.* import spock.lang.Specification
import org.junit.Test
class MapTest{ class MapTest extends Specification {
@Test
void createMap() {
def "createMap"() {
when:
def emptyMap = [:] def emptyMap = [:]
assertNotNull(emptyMap)
assertTrue(emptyMap instanceof java.util.LinkedHashMap)
def map = [name: "Jerry", age: 42, city: "New York"] def map = [name: "Jerry", age: 42, city: "New York"]
assertTrue(map.size() == 3)
then:
emptyMap != null
emptyMap instanceof java.util.LinkedHashMap
map.size() == 3
} }
@Test def "addItemsToMap"() {
void addItemsToMap() { given:
def map = [name: "Jerry"] def map = [name: "Jerry"]
map["age"] = 42
map.city = "New York"
def hobbyLiteral = "hobby" def hobbyLiteral = "hobby"
def hobbyMap = [(hobbyLiteral): "Singing"] def hobbyMap = [(hobbyLiteral): "Singing"]
def appendToMap = [:]
when:
map["age"] = 42
map.city = "New York"
map.putAll(hobbyMap) map.putAll(hobbyMap)
assertTrue(map == [name:"Jerry", age: 42, city: "New York", hobby:"Singing"]) appendToMap.plus([1: 20])
assertTrue(hobbyMap.hobby == "Singing") appendToMap << [2: 30]
assertTrue(hobbyMap[hobbyLiteral] == "Singing")
map.plus([1:20]) // returns new map then:
map == [name: "Jerry", age: 42, city: "New York", hobby: "Singing"]
map << [2:30] hobbyMap.hobby == "Singing"
hobbyMap[hobbyLiteral] == "Singing"
appendToMap == [2: 30] // plus(Map) returns new instance of Map
} }
@Test def "getItemsFromMap"() {
void getItemsFromMap() { when:
def map = [name: "Jerry", age: 42, city: "New York", hobby: "Singing"] def map = [name: "Jerry", age: 42, city: "New York", hobby: "Singing"]
assertTrue(map["name"] == "Jerry")
assertTrue(map.name == "Jerry")
def propertyAge = "age" def propertyAge = "age"
assertTrue(map[propertyAge] == 42)
then:
map["name"] == "Jerry"
map.name == "Jerry"
map[propertyAge] == 42
map."$propertyAge" == 42
} }
@Test def "removeItemsFromMap"() {
void removeItemsFromMap() { given:
def map = [1: 20, a: 30, 2: 42, 4: 34, ba: 67, 6: 39, 7: 49] def map = [1: 20, a: 30, 2: 42, 4: 34, ba: 67, 6: 39, 7: 49]
def removeAllKeysOfTypeString = [1: 20, a: 30, ba: 67, 6: 39, 7: 49]
def retainAllEntriesWhereValueIsEven = [1: 20, a: 30, ba: 67, 6: 39, 7: 49]
def minusMap = map.minus([2:42, 4:34]); when:
assertTrue(minusMap == [1:20, a:30, ba:67, 6:39, 7:49]) def minusMap = map - [2: 42, 4: 34]
removeAllKeysOfTypeString.removeAll { it.key instanceof String }
retainAllEntriesWhereValueIsEven.retainAll { it.value % 2 == 0 }
minusMap.removeAll{it -> it.key instanceof String} then:
assertTrue( minusMap == [ 1:20, 6:39, 7:49]) minusMap == [1: 20, a: 30, ba: 67, 6: 39, 7: 49]
removeAllKeysOfTypeString == [1: 20, 6: 39, 7: 49]
minusMap.retainAll{it -> it.value %2 == 0} retainAllEntriesWhereValueIsEven == [1: 20, a: 30]
assertTrue( minusMap == [1:20])
} }
@Test def "iteratingOnMaps"() {
void iteratingOnMaps(){ when:
def map = [name: "Jerry", age: 42, city: "New York", hobby: "Singing"] def map = [name: "Jerry", age: 42, city: "New York", hobby: "Singing"]
then:
map.each { entry -> println "$entry.key: $entry.value" } map.each { entry -> println "$entry.key: $entry.value" }
map.eachWithIndex { entry, i -> println "$i $entry.key: $entry.value" } map.eachWithIndex { entry, i -> println "$i $entry.key: $entry.value" }
map.eachWithIndex { key, value, i -> println "$i $key: $value" } map.eachWithIndex { key, value, i -> println "$i $key: $value" }
} }
@Test def "filteringAndSearchingMaps"() {
void filteringAndSearchingMaps(){ given:
def map = [name: "Jerry", age: 42, city: "New York", hobby: "Singing"] def map = [name: "Jerry", age: 42, city: "New York", hobby: "Singing"]
assertTrue(map.find{ it.value == "New York"}.key == "city") when:
def find = map.find { it.value == "New York" }
def finaAll = map.findAll { it.value == "New York" }
def grep = map.grep { it.value == "New York" }
def every = map.every { it -> it.value instanceof String }
def any = map.any { it -> it.value instanceof String }
assertTrue(map.findAll{ it.value == "New York"} == [city : "New York"]) then:
find.key == "city"
map.grep{it.value == "New York"}.each{ it -> assertTrue(it.key == "city" && it.value == "New York")} finaAll instanceof Map
finaAll == [city: "New York"]
assertTrue(map.every{it -> it.value instanceof String} == false) grep instanceof Collection
grep.each { it -> assert it.key == "city" && it.value == "New York" }
assertTrue(map.any{it -> it.value instanceof String} == true) every instanceof Boolean
!every
any instanceof Boolean
any
} }
@Test def "collect"() {
void collect(){ given:
def map = [
def map = [1: [name:"Jerry", age: 42, city: "New York"], 1: [name: "Jerry", age: 42, city: "New York"],
2: [name: "Long", age: 25, city: "New York"], 2: [name: "Long", age: 25, city: "New York"],
3: [name: "Dustin", age: 29, city: "New York"], 3: [name: "Dustin", age: 29, city: "New York"],
4: [name:"Dustin", age: 34, city: "New York"]] 4: [name: "Dustin", age: 34, city: "New York"]
]
when:
def names = map.collect { entry -> entry.value.name } // returns only list def names = map.collect { entry -> entry.value.name } // returns only list
assertTrue(names == ["Jerry", "Long", "Dustin", "Dustin"]) def uniqueNames = map.collect { entry -> entry.value.name }
.unique()
def uniqueNames = map.collect([] as HashSet){entry -> entry.value.name}
assertTrue(uniqueNames == ["Jerry", "Long", "Dustin"] as Set)
def idNames = map.collectEntries { key, value -> [key, value.name] } def idNames = map.collectEntries { key, value -> [key, value.name] }
assertTrue(idNames == [1:"Jerry", 2: "Long", 3:"Dustin", 4: "Dustin"]) def below30Names = map.findAll { it.value.age < 30 }
.collect { key, value -> value.name }
def below30Names = map.findAll{it.value.age < 30}.collect{key, value -> value.name}
assertTrue(below30Names == ["Long", "Dustin"])
then:
names == ["Jerry", "Long", "Dustin", "Dustin"]
uniqueNames == ["Jerry", "Long", "Dustin"]
idNames == [1: "Jerry", 2: "Long", 3: "Dustin", 4: "Dustin"]
below30Names == ["Long", "Dustin"]
} }
@Test def "group"() {
void group(){ given:
def map = [1: 20, 2: 40, 3: 11, 4: 93] def map = [1: 20, 2: 40, 3: 11, 4: 93]
when:
def subMap = map.groupBy { it.value % 2 } def subMap = map.groupBy { it.value % 2 }
println subMap
assertTrue(subMap == [0:[1:20, 2:40 ], 1:[3:11, 4:93]])
def keySubMap = map.subMap([1, 2]) def keySubMap = map.subMap([1, 2])
assertTrue(keySubMap == [1:20, 2:40])
then:
subMap == [0: [1: 20, 2: 40], 1: [3: 11, 4: 93]]
keySubMap == [1: 20, 2: 40]
} }
@Test def "sorting"() {
void sorting(){ given:
def map = [ab: 20, a: 40, cb: 11, ba: 93] def map = [ab: 20, a: 40, cb: 11, ba: 93]
when:
def naturallyOrderedMap = map.sort() def naturallyOrderedMap = map.sort()
assertTrue([a:40, ab:20, ba:93, cb:11] == naturallyOrderedMap)
def compSortedMap = map.sort({ k1, k2 -> k1 <=> k2 } as Comparator) def compSortedMap = map.sort({ k1, k2 -> k1 <=> k2 } as Comparator)
assertTrue([a:40, ab:20, ba:93, cb:11] == compSortedMap)
def cloSortedMap = map.sort({ it1, it2 -> it1.value <=> it1.value }) def cloSortedMap = map.sort({ it1, it2 -> it1.value <=> it1.value })
assertTrue([cb:11, ab:20, a:40, ba:93] == cloSortedMap)
then:
naturallyOrderedMap == [a: 40, ab: 20, ba: 93, cb: 11]
compSortedMap == [a: 40, ab: 20, ba: 93, cb: 11]
cloSortedMap == [cb: 11, ab: 20, a: 40, ba: 93]
} }
} }

View File

@ -103,8 +103,9 @@
<repositories> <repositories>
<repository> <repository>
<id>central</id> <id>maven_central</id>
<url>https://jcenter.bintray.com</url> <name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2/</url>
</repository> </repository>
</repositories> </repositories>

View File

@ -1,70 +1,74 @@
package com.baeldung.removeprefix package com.baeldung.removeprefix
import org.junit.Assert import spock.lang.Specification
import org.junit.Test
class RemovePrefixTest { class RemovePrefixTest extends Specification {
def "whenCasePrefixIsRemoved_thenReturnTrue"() {
@Test given:
public void whenCasePrefixIsRemoved_thenReturnTrue() {
def trimPrefix = { def trimPrefix = {
it.startsWith('Groovy-') ? it.minus('Groovy-') : it it.startsWith('Groovy-') ? it.minus('Groovy-') : it
} }
when:
def actual = trimPrefix("Groovy-Tutorials at Baeldung") def actual = trimPrefix("Groovy-Tutorials at Baeldung")
def expected = "Tutorials at Baeldung" def expected = "Tutorials at Baeldung"
Assert.assertEquals(expected, actual) then:
expected == actual
} }
@Test def "whenPrefixIsRemoved_thenReturnTrue"() {
public void whenPrefixIsRemoved_thenReturnTrue() { given:
String prefix = "groovy-" String prefix = "groovy-"
String trimPrefix = "Groovy-Tutorials at Baeldung" String trimPrefix = "Groovy-Tutorials at Baeldung"
def actual;
when:
def actual
if (trimPrefix.startsWithIgnoreCase(prefix)) { if (trimPrefix.startsWithIgnoreCase(prefix)) {
actual = trimPrefix.substring(prefix.length()) actual = trimPrefix.substring(prefix.length())
} }
def expected = "Tutorials at Baeldung" def expected = "Tutorials at Baeldung"
Assert.assertEquals(expected, actual) then:
expected == actual
} }
@Test def "whenPrefixIsRemovedUsingRegex_thenReturnTrue"() {
public void whenPrefixIsRemovedUsingRegex_thenReturnTrue() { given:
def regex = ~"^([Gg])roovy-" def regex = ~"^([Gg])roovy-"
String trimPrefix = "Groovy-Tutorials at Baeldung" String trimPrefix = "Groovy-Tutorials at Baeldung"
String actual = trimPrefix - regex
when:
String actual = trimPrefix - regex
def expected = "Tutorials at Baeldung" def expected = "Tutorials at Baeldung"
Assert.assertEquals(expected, actual) then:
expected == actual
} }
@Test def "whenPrefixIsRemovedUsingReplaceFirst_thenReturnTrue"() {
public void whenPrefixIsRemovedUsingReplaceFirst_thenReturnTrue() { given:
def regex = ~"^groovy" def regex = ~"^groovy"
String trimPrefix = "groovyTutorials at Baeldung's groovy page" String trimPrefix = "groovyTutorials at Baeldung's groovy page"
String actual = trimPrefix.replaceFirst(regex, "")
when:
String actual = trimPrefix.replaceFirst(regex, "")
def expected = "Tutorials at Baeldung's groovy page" def expected = "Tutorials at Baeldung's groovy page"
Assert.assertEquals(expected, actual) then:
expected == actual
} }
@Test def "whenPrefixIsRemovedUsingReplaceAll_thenReturnTrue"() {
public void whenPrefixIsRemovedUsingReplaceAll_thenReturnTrue() { given:
String trimPrefix = "groovyTutorials at Baeldung groovy" String trimPrefix = "groovyTutorials at Baeldung groovy"
String actual = trimPrefix.replaceAll(/^groovy/, "")
when:
String actual = trimPrefix.replaceAll(/^groovy/, "")
def expected = "Tutorials at Baeldung groovy" def expected = "Tutorials at Baeldung groovy"
Assert.assertEquals(expected, actual) then:
expected == actual
} }
} }

View File

@ -3,6 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>core-groovy</artifactId> <artifactId>core-groovy</artifactId>
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<name>core-groovy</name> <name>core-groovy</name>
@ -103,8 +104,9 @@
<repositories> <repositories>
<repository> <repository>
<id>central</id> <id>maven_central</id>
<url>https://jcenter.bintray.com</url> <name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2/</url>
</repository> </repository>
</repositories> </repositories>

View File

@ -10,13 +10,14 @@ class ReadFile {
int readFileLineByLine(String filePath) { int readFileLineByLine(String filePath) {
File file = new File(filePath) File file = new File(filePath)
def line, noOfLines = 0; def line, noOfLines = 0;
file.withReader { reader -> file.withReader { reader ->
while ((line = reader.readLine())!=null) while ((line = reader.readLine()) != null) {
{
println "${line}" println "${line}"
noOfLines++ noOfLines++
} }
} }
return noOfLines return noOfLines
} }
@ -26,9 +27,7 @@ class ReadFile {
* @return * @return
*/ */
List<String> readFileInList(String filePath) { List<String> readFileInList(String filePath) {
File file = new File(filePath) return new File(filePath).readLines()
def lines = file.readLines()
return lines
} }
/** /**
@ -37,9 +36,7 @@ class ReadFile {
* @return * @return
*/ */
String readFileString(String filePath) { String readFileString(String filePath) {
File file = new File(filePath) return new File(filePath).text
String fileContent = file.text
return fileContent
} }
/** /**
@ -48,9 +45,7 @@ class ReadFile {
* @return * @return
*/ */
String readFileStringWithCharset(String filePath) { String readFileStringWithCharset(String filePath) {
File file = new File(filePath) return new File(filePath).getText("UTF-8")
String utf8Content = file.getText("UTF-8")
return utf8Content
} }
/** /**
@ -59,9 +54,7 @@ class ReadFile {
* @return * @return
*/ */
byte[] readBinaryFile(String filePath) { byte[] readBinaryFile(String filePath) {
File file = new File(filePath) return new File(filePath).bytes
byte[] binaryContent = file.bytes
return binaryContent
} }
/** /**
@ -85,16 +78,14 @@ class ReadFile {
def array = new File("src/main/resources/fileContent.txt") as String[] def array = new File("src/main/resources/fileContent.txt") as String[]
// eachline // eachline
new File("src/main/resources/fileContent.txt").eachLine { line -> new File("src/main/resources/fileContent.txt").eachLine { println it }
println line
}
//newInputStream with eachLine //newInputStream with eachLine
def is = new File("src/main/resources/fileContent.txt").newInputStream()
is.eachLine { // try-with-resources automatically closes BufferedInputStream resource
println it try (def inputStream = new File("src/main/resources/fileContent.txt").newInputStream()) {
inputStream.eachLine { println it }
} }
is.close()
// withInputStream // withInputStream
new File("src/main/resources/fileContent.txt").withInputStream { stream -> new File("src/main/resources/fileContent.txt").withInputStream { stream ->
@ -103,5 +94,4 @@ class ReadFile {
} }
} }
} }
} }

View File

@ -1,6 +1,7 @@
package com.baeldung.strings; package com.baeldung.strings;
class Concatenate { class Concatenate {
String first = 'Hello' String first = 'Hello'
String last = 'Groovy' String last = 'Groovy'
@ -30,14 +31,21 @@ class Concatenate {
String doConcatUsingArrayInjectMethod() { String doConcatUsingArrayInjectMethod() {
return [first, ' ', last] return [first, ' ', last]
.inject(new StringBuffer('My name is '), { initial, name -> initial.append(name); return initial }).toString() .inject(new StringBuffer('My name is '), { initial, name -> initial.append(name) })
.toString()
} }
String doConcatUsingStringBuilder() { String doConcatUsingStringBuilder() {
return new StringBuilder().append('My name is ').append(first).append(' ').append(last) return new StringBuilder().append('My name is ')
.append(first)
.append(' ')
.append(last)
} }
String doConcatUsingStringBuffer() { String doConcatUsingStringBuffer() {
return new StringBuffer().append('My name is ').append(first).append(' ').append(last) return new StringBuffer().append('My name is ')
.append(first)
.append(' ')
.append(last)
} }
} }

View File

@ -5,5 +5,4 @@ class Dog implements WalkingTrait, SpeakingTrait {
String speakAndWalk() { String speakAndWalk() {
WalkingTrait.super.speakAndWalk() WalkingTrait.super.speakAndWalk()
} }
} }

View File

@ -2,10 +2,12 @@ package com.baeldung.traits
class Employee implements UserTrait { class Employee implements UserTrait {
@Override
String name() { String name() {
return 'Bob' return 'Bob'
} }
@Override
String lastName() { String lastName() {
return "Marley" return "Marley"
} }

View File

@ -9,5 +9,4 @@ trait SpeakingTrait {
String speakAndWalk() { String speakAndWalk() {
return "Speak and walk!!" return "Speak and walk!!"
} }
} }

View File

@ -2,12 +2,15 @@ package com.baeldung.traits
trait UserTrait implements Human { trait UserTrait implements Human {
String email
String address
abstract String name()
String sayHello() { String sayHello() {
return "Hello!" return "Hello!"
} }
abstract String name()
String showName() { String showName() {
return "Hello, ${name()}!" return "Hello, ${name()}!"
} }
@ -29,8 +32,4 @@ trait UserTrait implements Human {
String showLastName() { String showLastName() {
return "Hello, ${lastName()}!" return "Hello, ${lastName()}!"
} }
String email
String address
} }

View File

@ -3,5 +3,4 @@ package com.baeldung
trait WheelTrait { trait WheelTrait {
int noOfWheels int noOfWheels
} }

View File

@ -1,7 +1,6 @@
package com.baeldung.file package com.baeldung.file
import spock.lang.Specification import spock.lang.Specification
import spock.lang.Ignore
class ReadFileUnitTest extends Specification { class ReadFileUnitTest extends Specification {
@ -14,44 +13,49 @@ class ReadFileUnitTest extends Specification {
def 'Should return number of lines in File using ReadFile.readFileLineByLine given filePath'() { def 'Should return number of lines in File using ReadFile.readFileLineByLine given filePath'() {
given: given:
def filePath = "src/main/resources/fileContent.txt" def filePath = "src/main/resources/fileContent.txt"
when: when:
def noOfLines = readFile.readFileLineByLine(filePath) def noOfLines = readFile.readFileLineByLine(filePath)
then: then:
noOfLines noOfLines
noOfLines instanceof Integer noOfLines instanceof Integer
assert noOfLines, 3 noOfLines == 3
} }
def 'Should return File Content in list of lines using ReadFile.readFileInList given filePath'() { def 'Should return File Content in list of lines using ReadFile.readFileInList given filePath'() {
given: given:
def filePath = "src/main/resources/fileContent.txt" def filePath = "src/main/resources/fileContent.txt"
when: when:
def lines = readFile.readFileInList(filePath) def lines = readFile.readFileInList(filePath)
then: then:
lines lines
lines instanceof List<String> lines instanceof List<String>
assert lines.size(), 3 lines.size() == 3
} }
def 'Should return file content in string using ReadFile.readFileString given filePath'() { def 'Should return file content in string using ReadFile.readFileString given filePath'() {
given: given:
def filePath = "src/main/resources/fileContent.txt" def filePath = "src/main/resources/fileContent.txt"
when: when:
def fileContent = readFile.readFileString(filePath) def fileContent = readFile.readFileString(filePath)
then: then:
fileContent fileContent
fileContent instanceof String fileContent instanceof String
fileContent.contains("""Line 1 : Hello World!!! fileContent.contains(["Line 1 : Hello World!!!", "Line 2 : This is a file content.", "Line 3 : String content"].join("\r\n"))
Line 2 : This is a file content.
Line 3 : String content""")
} }
def 'Should return UTF-8 encoded file content in string using ReadFile.readFileStringWithCharset given filePath'() { def 'Should return UTF-8 encoded file content in string using ReadFile.readFileStringWithCharset given filePath'() {
given: given:
def filePath = "src/main/resources/utf8Content.html" def filePath = "src/main/resources/utf8Content.html"
when: when:
def encodedContent = readFile.readFileStringWithCharset(filePath) def encodedContent = readFile.readFileStringWithCharset(filePath)
then: then:
encodedContent encodedContent
encodedContent instanceof String encodedContent instanceof String
@ -60,12 +64,13 @@ Line 3 : String content""")
def 'Should return binary file content in byte array using ReadFile.readBinaryFile given filePath'() { def 'Should return binary file content in byte array using ReadFile.readBinaryFile given filePath'() {
given: given:
def filePath = "src/main/resources/sample.png" def filePath = "src/main/resources/sample.png"
when: when:
def binaryContent = readFile.readBinaryFile(filePath) def binaryContent = readFile.readBinaryFile(filePath)
then: then:
binaryContent binaryContent
binaryContent instanceof byte[] binaryContent instanceof byte[]
binaryContent.length == 329 binaryContent.length == 329
} }
} }

View File

@ -1,28 +1,29 @@
package com.baeldung.groovy.sql package com.baeldung.groovy.sql
import groovy.sql.GroovyResultSet import groovy.sql.GroovyResultSet
import groovy.sql.GroovyRowResult
import groovy.sql.Sql import groovy.sql.Sql
import groovy.transform.CompileStatic
import static org.junit.Assert.*
import org.junit.Test import org.junit.Test
import static org.junit.Assert.*
class SqlTest { class SqlTest {
final Map dbConnParams = [url: 'jdbc:hsqldb:mem:testDB', user: 'sa', password: '', driver: 'org.hsqldb.jdbc.JDBCDriver'] final Map dbConnParams = [url: 'jdbc:hsqldb:mem:testDB',
user: 'sa',
password: '',
driver: 'org.hsqldb.jdbc.JDBCDriver']
@Test @Test
void whenNewSqlInstance_thenDbIsAccessed() { void whenNewSqlInstance_thenDbIsAccessed() {
def sql = Sql.newInstance(dbConnParams) def sql = Sql.newInstance(dbConnParams)
sql.close() sql.close()
sql.close()
} }
@Test @Test
void whenTableDoesNotExist_thenSelectFails() { void whenTableDoesNotExist_thenSelectFails() {
try { try {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.eachRow('select * from PROJECT') {} sql.eachRow('SELECT * FROM PROJECT') {}
} }
fail("An exception should have been thrown") fail("An exception should have been thrown")
@ -34,12 +35,12 @@ class SqlTest {
@Test @Test
void whenTableCreated_thenSelectIsPossible() { void whenTableCreated_thenSelectIsPossible() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
def result = sql.execute 'create table PROJECT_1 (id integer not null, name varchar(50), url varchar(100))' def result = sql.execute 'CREATE TABLE PROJECT_1 (ID INTEGER NOT NULL, NAME VARCHAR(50), URL VARCHAR(100))'
assertEquals(0, sql.updateCount) assertEquals(0, sql.updateCount)
assertFalse(result) assertFalse(result)
result = sql.execute('select * from PROJECT_1') result = sql.execute('SELECT * FROM PROJECT_1')
assertTrue(result) assertTrue(result)
} }
@ -48,7 +49,7 @@ class SqlTest {
@Test @Test
void whenIdentityColumn_thenInsertReturnsNewId() { void whenIdentityColumn_thenInsertReturnsNewId() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.execute 'create table PROJECT_2 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_2 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
def ids = sql.executeInsert("INSERT INTO PROJECT_2 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')") def ids = sql.executeInsert("INSERT INTO PROJECT_2 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')")
assertEquals(0, ids[0][0]) assertEquals(0, ids[0][0])
@ -62,9 +63,10 @@ class SqlTest {
@Test @Test
void whenUpdate_thenNumberOfAffectedRows() { void whenUpdate_thenNumberOfAffectedRows() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.execute 'create table PROJECT_3 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_3 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.executeInsert("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')") sql.executeInsert("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')")
sql.executeInsert("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')") sql.executeInsert("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')")
def count = sql.executeUpdate("UPDATE PROJECT_3 SET URL = 'https://' + URL") def count = sql.executeUpdate("UPDATE PROJECT_3 SET URL = 'https://' + URL")
assertEquals(2, count) assertEquals(2, count)
@ -74,7 +76,7 @@ class SqlTest {
@Test @Test
void whenEachRow_thenResultSetHasProperties() { void whenEachRow_thenResultSetHasProperties() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.execute 'create table PROJECT_4 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_4 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.executeInsert("INSERT INTO PROJECT_4 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") sql.executeInsert("INSERT INTO PROJECT_4 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
sql.executeInsert("INSERT INTO PROJECT_4 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')") sql.executeInsert("INSERT INTO PROJECT_4 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')")
@ -93,7 +95,7 @@ class SqlTest {
@Test @Test
void whenPagination_thenSubsetIsReturned() { void whenPagination_thenSubsetIsReturned() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.execute 'create table PROJECT_5 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_5 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')") sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')")
sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')") sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')")
def rows = sql.rows('SELECT * FROM PROJECT_5 ORDER BY NAME', 1, 1) def rows = sql.rows('SELECT * FROM PROJECT_5 ORDER BY NAME', 1, 1)
@ -106,9 +108,11 @@ class SqlTest {
@Test @Test
void whenParameters_thenReplacement() { void whenParameters_thenReplacement() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.execute 'create table PROJECT_6 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_6 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.execute('INSERT INTO PROJECT_6 (NAME, URL) VALUES (?, ?)', 'tutorials', 'github.com/eugenp/tutorials') sql.execute('INSERT INTO PROJECT_6 (NAME, URL) VALUES (?, ?)',
sql.execute("INSERT INTO PROJECT_6 (NAME, URL) VALUES (:name, :url)", [name: 'REST with Spring', url: 'github.com/eugenp/REST-With-Spring']) 'tutorials', 'github.com/eugenp/tutorials')
sql.execute("INSERT INTO PROJECT_6 (NAME, URL) VALUES (:name, :url)",
[name: 'REST with Spring', url: 'github.com/eugenp/REST-With-Spring'])
def rows = sql.rows("SELECT * FROM PROJECT_6 WHERE NAME = 'tutorials'") def rows = sql.rows("SELECT * FROM PROJECT_6 WHERE NAME = 'tutorials'")
@ -123,7 +127,7 @@ class SqlTest {
@Test @Test
void whenParametersInGString_thenReplacement() { void whenParametersInGString_thenReplacement() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.execute 'create table PROJECT_7 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_7 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.execute "INSERT INTO PROJECT_7 (NAME, URL) VALUES (${'tutorials'}, ${'github.com/eugenp/tutorials'})" sql.execute "INSERT INTO PROJECT_7 (NAME, URL) VALUES (${'tutorials'}, ${'github.com/eugenp/tutorials'})"
def name = 'REST with Spring' def name = 'REST with Spring'
def url = 'github.com/eugenp/REST-With-Spring' def url = 'github.com/eugenp/REST-With-Spring'
@ -143,7 +147,7 @@ class SqlTest {
void whenTransactionRollback_thenNoDataInserted() { void whenTransactionRollback_thenNoDataInserted() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.withTransaction { sql.withTransaction {
sql.execute 'create table PROJECT_8 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_8 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.executeInsert("INSERT INTO PROJECT_8 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") sql.executeInsert("INSERT INTO PROJECT_8 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
sql.executeInsert("INSERT INTO PROJECT_8 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')") sql.executeInsert("INSERT INTO PROJECT_8 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')")
sql.rollback() sql.rollback()
@ -159,7 +163,7 @@ class SqlTest {
void whenTransactionRollbackThenCommit_thenOnlyLastInserted() { void whenTransactionRollbackThenCommit_thenOnlyLastInserted() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.withTransaction { sql.withTransaction {
sql.execute 'create table PROJECT_9 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_9 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
sql.rollback() sql.rollback()
sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')") sql.executeInsert("INSERT INTO PROJECT_9 (NAME, URL) VALUES ('REST with Spring', 'https://github.com/eugenp/REST-With-Spring')")
@ -179,11 +183,12 @@ class SqlTest {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
try { try {
sql.withTransaction { sql.withTransaction {
sql.execute 'create table PROJECT_10 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_10 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.executeInsert("INSERT INTO PROJECT_10 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") sql.executeInsert("INSERT INTO PROJECT_10 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
throw new Exception('rollback') throw new Exception('rollback')
} }
} catch (ignored) {} } catch (ignored) {
}
def rows = sql.rows("SELECT * FROM PROJECT_10") def rows = sql.rows("SELECT * FROM PROJECT_10")
@ -196,11 +201,12 @@ class SqlTest {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
try { try {
sql.cacheConnection { sql.cacheConnection {
sql.execute 'create table PROJECT_11 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_11 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.executeInsert("INSERT INTO PROJECT_11 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')") sql.executeInsert("INSERT INTO PROJECT_11 (NAME, URL) VALUES ('tutorials', 'https://github.com/eugenp/tutorials')")
throw new Exception('This does not rollback') throw new Exception('This does not rollback')
} }
} catch (ignored) {} } catch (ignored) {
}
def rows = sql.rows("SELECT * FROM PROJECT_11") def rows = sql.rows("SELECT * FROM PROJECT_11")
@ -211,7 +217,7 @@ class SqlTest {
/*@Test /*@Test
void whenModifyResultSet_thenDataIsChanged() { void whenModifyResultSet_thenDataIsChanged() {
Sql.withInstance(dbConnParams) { Sql sql -> Sql.withInstance(dbConnParams) { Sql sql ->
sql.execute 'create table PROJECT_5 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))' sql.execute 'CREATE TABLE PROJECT_5 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))'
sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')") sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')")
sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')") sql.executeInsert("INSERT INTO PROJECT_5 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')")

View File

@ -1,5 +1,6 @@
package com.baeldung.json package com.baeldung.json
import groovy.json.JsonGenerator
import spock.lang.Specification import spock.lang.Specification
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -15,8 +16,10 @@ class JsonParserTest extends Specification {
def 'Should parse to Account given Json String'() { def 'Should parse to Account given Json String'() {
given: given:
def json = '{"id":"1234","value":15.6}' def json = '{"id":"1234","value":15.6}'
when: when:
def account = jsonParser.toObject(json) def account = jsonParser.toObject(json)
then: then:
account account
account instanceof Account account instanceof Account
@ -24,6 +27,26 @@ class JsonParserTest extends Specification {
account.value == 15.6 account.value == 15.6
} }
def 'Should format date and exclude value field'() {
given:
def account = new Account(
id: '123',
value: 15.6,
createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('14/01/2023')
)
def jsonGenerator = new JsonGenerator.Options()
.dateFormat('MM/dd/yyyy')
.excludeFieldsByName('value')
.build()
when:
def accountToJson = jsonGenerator.toJson(account)
then:
accountToJson == '{"createdAt":"01/31/2024","id":"123"}'
}
/*def 'Should parse to Account given Json String with date property' () { /*def 'Should parse to Account given Json String with date property' () {
given: given:
def json = '{"id":"1234","value":15.6,"createdAt":"2018-01-01T00:00:00+0000"}' def json = '{"id":"1234","value":15.6,"createdAt":"2018-01-01T00:00:00+0000"}'
@ -55,12 +78,17 @@ class JsonParserTest extends Specification {
def 'Should prettify given a json string'() { def 'Should prettify given a json string'() {
given: given:
String json = '{"value":15.6,"createdAt":"01/01/2018","id":"123456"}' String json = '{"value":15.6,"createdAt":"01/01/2018","id":"123456"}'
when: when:
def jsonPretty = jsonParser.prettyfy(json) def jsonPretty = jsonParser.prettyfy(json)
then: then:
jsonPretty jsonPretty
jsonPretty == '{\n "value": 15.6,\n "createdAt": "01/01/2018",\n "id": "123456"\n}' jsonPretty == '''\
{
"value": 15.6,
"createdAt": "01/01/2018",
"id": "123456"
}'''
} }
} }

View File

@ -1,101 +1,88 @@
import com.baeldung.strings.Concatenate; import com.baeldung.strings.Concatenate
import spock.lang.Specification
class ConcatenateTest extends GroovyTestCase { class ConcatenateTest extends Specification {
void testSimpleConcat() { final Concatenate NAME = new Concatenate(first: 'Joe', last: 'Smith')
def name = new Concatenate() final String EXPECTED = "My name is Joe Smith";
name.first = 'Joe';
name.last = 'Smith'; def "SimpleConcat"() {
def expected = 'My name is Joe Smith' expect:
assertToString(name.doSimpleConcat(), expected) NAME.doSimpleConcat() == EXPECTED
} }
void testConcatUsingGString() { def "ConcatUsingGString"() {
def name = new Concatenate() expect:
name.first = "Joe"; NAME.doConcatUsingGString() == EXPECTED
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingGString(), expected)
} }
void testConcatUsingGStringClosures() { def "ConcatUsingGStringClosures"() {
def name = new Concatenate() expect:
name.first = "Joe"; NAME.doConcatUsingGStringClosures() == EXPECTED
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingGStringClosures(), expected)
} }
void testConcatUsingStringConcatMethod() { def "ConcatUsingStringConcatMethod"() {
def name = new Concatenate() expect:
name.first = "Joe"; NAME.doConcatUsingStringConcatMethod() == EXPECTED
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingStringConcatMethod(), expected)
} }
void testConcatUsingLeftShiftOperator() { def "ConcatUsingLeftShiftOperator"() {
def name = new Concatenate() expect:
name.first = "Joe"; NAME.doConcatUsingLeftShiftOperator() == EXPECTED
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingLeftShiftOperator(), expected)
} }
void testConcatUsingArrayJoinMethod() { def "ConcatUsingArrayJoinMethod"() {
def name = new Concatenate() expect:
name.first = "Joe"; NAME.doConcatUsingArrayJoinMethod() == EXPECTED
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingArrayJoinMethod(), expected)
} }
void testConcatUsingArrayInjectMethod() { def "ConcatUsingArrayInjectMethod"() {
def name = new Concatenate() expect:
name.first = "Joe"; NAME.doConcatUsingArrayInjectMethod() == EXPECTED
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingArrayInjectMethod(), expected)
} }
void testConcatUsingStringBuilder() { def "ConcatUsingStringBuilder"() {
def name = new Concatenate() expect:
name.first = "Joe"; NAME.doConcatUsingStringBuilder() == EXPECTED
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingStringBuilder(), expected)
} }
void testConcatUsingStringBuffer() { def "ConcatUsingStringBuffer"() {
def name = new Concatenate() expect:
name.first = "Joe"; NAME.doConcatUsingStringBuffer() == EXPECTED
name.last = "Smith";
def expected = "My name is Joe Smith"
assertToString(name.doConcatUsingStringBuffer(), expected)
} }
void testConcatMultilineUsingStringConcatMethod() { def "ConcatMultilineUsingStringConcatMethod"() {
def name = new Concatenate() when:
name.first = '''Joe NAME.first = '''Joe
Smith Smith
'''; '''
name.last = 'Junior'; NAME.last = 'Junior'
then:
def expected = '''My name is Joe def expected = '''My name is Joe
Smith Smith
Junior'''; Junior'''
assertToString(name.doConcatUsingStringConcatMethod(), expected) NAME.doConcatUsingStringConcatMethod() == expected
} }
void testGStringvsClosure(){ def "GStringvsClosure"() {
def first = "Joe"; given:
def last = "Smith"; def eagerGString = "My name is $NAME.first $NAME.last"
def eagerGString = "My name is $first $last" def lazyGString = "My name is ${-> NAME.first} ${-> NAME.last}"
def lazyGString = "My name is ${-> first} ${-> last}"
assert eagerGString == "My name is Joe Smith" expect:
assert lazyGString == "My name is Joe Smith" eagerGString == "My name is Joe Smith"
first = "David"; lazyGString == "My name is Joe Smith"
assert eagerGString == "My name is Joe Smith" }
assert lazyGString == "My name is David Smith"
def "LazyVsEager"() {
given:
def eagerGString = "My name is $NAME.first $NAME.last"
def lazyGString = "My name is ${-> NAME.first} ${-> NAME.last}"
NAME.first = "David"
expect:
eagerGString == "My name is Joe Smith"
lazyGString == "My name is David Smith"
} }
} }

View File

@ -13,7 +13,7 @@ class StringMatchingSpec extends Specification {
expect: expect:
p instanceof Pattern p instanceof Pattern
and: "you can use slash strings to avoid escaping of blackslash" and: "you can use slash strings to avoid escaping of backslash"
def digitPattern = ~/\d*/ def digitPattern = ~/\d*/
digitPattern.matcher('4711').matches() digitPattern.matcher('4711').matches()
} }

View File

@ -1,110 +1,119 @@
package com.baeldung.stringtoint package com.baeldung.stringtoint
import org.junit.Test import spock.lang.Specification
import java.text.DecimalFormat import java.text.DecimalFormat
import static org.junit.Assert.assertEquals class ConvertStringToInt extends Specification {
import static org.junit.Assert.assertNull
class ConvertStringToInt { final String STRING_NUM = "123"
final int EXPECTED_INT = 123
@Test def "givenString_whenUsingAsInteger_thenConvertToInteger"() {
void givenString_whenUsingAsInteger_thenConvertToInteger() { given:
def stringNum = "123"
def invalidString = "123a" def invalidString = "123a"
Integer expectedInteger = 123 Integer integerNum = STRING_NUM as Integer
Integer integerNum = stringNum as Integer
when:
def intNum = invalidString?.isInteger() ? invalidString as Integer : null def intNum = invalidString?.isInteger() ? invalidString as Integer : null
assertNull(null, intNum) then:
assertEquals(integerNum, expectedInteger) intNum == null
integerNum == EXPECTED_INT
} }
@Test def "givenString_whenUsingAsInt_thenConvertToInt"() {
void givenString_whenUsingAsInt_thenConvertToInt() { given:
def stringNum = "123" int intNum = STRING_NUM as int
int expectedInt = 123
int intNum = stringNum as int
assertEquals(intNum, expectedInt) expect:
intNum == EXPECTED_INT
} }
@Test def "givenString_whenUsingToInteger_thenConvertToInteger"() {
void givenString_whenUsingToInteger_thenConvertToInteger() { given:
def stringNum = "123" int intNum = STRING_NUM.toInteger()
int expectedInt = 123
int intNum = stringNum.toInteger()
assertEquals(intNum, expectedInt) expect:
intNum == EXPECTED_INT
} }
@Test def "givenString_whenUsingParseInt_thenConvertToInteger"() {
void givenString_whenUsingParseInt_thenConvertToInteger() { given:
def stringNum = "123" int intNum = Integer.parseInt(STRING_NUM)
int expectedInt = 123
int intNum = Integer.parseInt(stringNum)
assertEquals(intNum, expectedInt) expect:
intNum == EXPECTED_INT
} }
@Test def "givenString_whenUsingValueOf_thenConvertToInteger"() {
void givenString_whenUsingValueOf_thenConvertToInteger() { given:
def stringNum = "123" int intNum = Integer.valueOf(STRING_NUM)
int expectedInt = 123
int intNum = Integer.valueOf(stringNum)
assertEquals(intNum, expectedInt) expect:
intNum == EXPECTED_INT
} }
@Test def "givenString_whenUsingIntValue_thenConvertToInteger"() {
void givenString_whenUsingIntValue_thenConvertToInteger() { given:
def stringNum = "123" int intNum = Integer.valueOf(STRING_NUM).intValue()
int expectedInt = 123
int intNum = new Integer(stringNum).intValue()
assertEquals(intNum, expectedInt) expect:
intNum == EXPECTED_INT
} }
@Test def "givenString_whenUsingNewInteger_thenConvertToInteger"() {
void givenString_whenUsingNewInteger_thenConvertToInteger() { given:
def stringNum = "123" Integer intNum = Integer.valueOf(STRING_NUM)
int expectedInt = 123
int intNum = new Integer(stringNum)
assertEquals(intNum, expectedInt) expect:
intNum == EXPECTED_INT
} }
@Test def "givenString_whenUsingDecimalFormat_thenConvertToInteger"() {
void givenString_whenUsingDecimalFormat_thenConvertToInteger() { given:
def stringNum = "123"
int expectedInt = 123
DecimalFormat decimalFormat = new DecimalFormat("#") DecimalFormat decimalFormat = new DecimalFormat("#")
int intNum = decimalFormat.parse(stringNum).intValue()
assertEquals(intNum, expectedInt) when:
int intNum = decimalFormat.parse(STRING_NUM).intValue()
then:
intNum == EXPECTED_INT
} }
@Test(expected = NumberFormatException.class) def "givenInvalidString_whenUsingAs_thenThrowNumberFormatException"() {
void givenInvalidString_whenUsingAs_thenThrowNumberFormatException() { given:
def invalidString = "123a" def invalidString = "123a"
when:
invalidString as Integer invalidString as Integer
then:
thrown(NumberFormatException)
} }
@Test(expected = NullPointerException.class) def "givenNullString_whenUsingToInteger_thenThrowNullPointerException"() {
void givenNullString_whenUsingToInteger_thenThrowNullPointerException() { given:
def invalidString = null def invalidString = null
when:
invalidString.toInteger() invalidString.toInteger()
then:
thrown(NullPointerException)
} }
@Test def "givenString_whenUsingIsInteger_thenCheckIfCorrectValue"() {
void givenString_whenUsingIsInteger_thenCheckIfCorrectValue() { given:
def invalidString = "123a" def invalidString = "123a"
def validString = "123" def validString = "123"
when:
def invalidNum = invalidString?.isInteger() ? invalidString as Integer : false def invalidNum = invalidString?.isInteger() ? invalidString as Integer : false
def correctNum = validString?.isInteger() ? validString as Integer : false def correctNum = validString?.isInteger() ? validString as Integer : false
assertEquals(false, invalidNum) then:
assertEquals(123, correctNum) !invalidNum
correctNum == 123
} }
} }

View File

@ -1,19 +1,18 @@
package groovy.com.baeldung.stringtypes package groovy.com.baeldung.stringtypes
import org.junit.Assert import spock.lang.Specification
import org.junit.Test
class CharacterInGroovy { class CharacterInGroovy extends Specification {
@Test def 'character'() {
void 'character'() { given:
char a = 'A' as char char a = 'A' as char
char b = 'B' as char char b = 'B' as char
char c = (char) 'C' char c = (char) 'C'
Assert.assertTrue(a instanceof Character) expect:
Assert.assertTrue(b instanceof Character) a instanceof Character
Assert.assertTrue(c instanceof Character) b instanceof Character
c instanceof Character
} }
} }

View File

@ -1,67 +1,76 @@
package groovy.com.baeldung.stringtypes package groovy.com.baeldung.stringtypes
import org.junit.Assert import spock.lang.Specification
import org.junit.Test
class DoubleQuotedString { class DoubleQuotedString extends Specification {
@Test def 'escape double quoted string'() {
void 'escape double quoted string'() { given:
def example = "Hello \"world\"!" def example = "Hello \"world\"!"
println(example) expect:
example == 'Hello "world"!'
} }
@Test def 'String ang GString'() {
void 'String ang GString'() { given:
def string = "example" def string = "example"
def stringWithExpression = "example${2}" def stringWithExpression = "example${2}"
Assert.assertTrue(string instanceof String) expect:
Assert.assertTrue(stringWithExpression instanceof GString) string instanceof String
Assert.assertTrue(stringWithExpression.toString() instanceof String) stringWithExpression instanceof GString
stringWithExpression.toString() instanceof String
} }
@Test def 'placeholder with variable'() {
void 'placeholder with variable'() { given:
def name = "John" def name = "John"
when:
def helloName = "Hello $name!".toString() def helloName = "Hello $name!".toString()
Assert.assertEquals("Hello John!", helloName) then:
helloName == "Hello John!"
} }
@Test def 'placeholder with expression'() {
void 'placeholder with expression'() { given:
def result = "result is ${2 * 2}".toString() def result = "result is ${2 * 2}".toString()
Assert.assertEquals("result is 4", result) expect:
result == "result is 4"
} }
@Test def 'placeholder with dotted access'() {
void 'placeholder with dotted access'() { given:
def person = [name: 'John'] def person = [name: 'John']
when:
def myNameIs = "I'm $person.name, and you?".toString() def myNameIs = "I'm $person.name, and you?".toString()
Assert.assertEquals("I'm John, and you?", myNameIs) then:
myNameIs == "I'm John, and you?"
} }
@Test def 'placeholder with method call'() {
void 'placeholder with method call'() { given:
def name = 'John' def name = 'John'
when:
def result = "Uppercase name: ${name.toUpperCase()}".toString() def result = "Uppercase name: ${name.toUpperCase()}".toString()
Assert.assertEquals("Uppercase name: JOHN", result) then:
result == "Uppercase name: JOHN"
} }
@Test def 'GString and String hashcode'() {
void 'GString and String hashcode'() { given:
def string = "2+2 is 4" def string = "2+2 is 4"
def gstring = "2+2 is ${4}" def gstring = "2+2 is ${4}"
Assert.assertTrue(string.hashCode() != gstring.hashCode()) expect:
string.hashCode() != gstring.hashCode()
} }
} }

View File

@ -1,15 +1,14 @@
package groovy.com.baeldung.stringtypes package groovy.com.baeldung.stringtypes
import org.junit.Assert import spock.lang.Specification
import org.junit.Test
class SingleQuotedString { class SingleQuotedString extends Specification {
@Test def 'single quoted string'() {
void 'single quoted string'() { given:
def example = 'Hello world' def example = 'Hello world!'
Assert.assertEquals('Hello world!', 'Hello' + ' world!') expect:
example == 'Hello' + ' world!'
} }
} }

View File

@ -1,26 +1,29 @@
package groovy.com.baeldung.stringtypes package groovy.com.baeldung.stringtypes
import org.junit.Assert import spock.lang.Specification
import org.junit.Test
class Strings { class Strings extends Specification {
@Test def 'string interpolation '() {
void 'string interpolation '() { given:
def name = "Kacper" def name = "Kacper"
when:
def result = "Hello ${name}!" def result = "Hello ${name}!"
Assert.assertEquals("Hello Kacper!", result.toString()) then:
result.toString() == "Hello Kacper!"
} }
@Test def 'string concatenation'() {
void 'string concatenation'() { given:
def first = "first" def first = "first"
def second = "second" def second = "second"
when:
def concatenation = first + second def concatenation = first + second
Assert.assertEquals("firstsecond", concatenation) then:
concatenation == "firstsecond"
} }
} }

View File

@ -15,100 +15,103 @@ class TraitsUnitTest extends Specification {
def 'Should return msg string when using Employee.sayHello method provided by UserTrait'() { def 'Should return msg string when using Employee.sayHello method provided by UserTrait'() {
when: when:
def msg = employee.sayHello() def msg = employee.sayHello()
then: then:
msg msg
msg instanceof String msg instanceof String
assert msg == "Hello!" msg == "Hello!"
} }
def 'Should return displayMsg string when using Employee.showName method'() { def 'Should return displayMsg string when using Employee.showName method'() {
when: when:
def displayMsg = employee.showName() def displayMsg = employee.showName()
then: then:
displayMsg displayMsg
displayMsg instanceof String displayMsg instanceof String
assert displayMsg == "Hello, Bob!" displayMsg == "Hello, Bob!"
} }
def 'Should return greetMsg string when using Employee.greet method'() { def 'Should return greetMsg string when using Employee.greet method'() {
when: when:
def greetMsg = employee.greet() def greetMsg = employee.greet()
then: then:
greetMsg greetMsg
greetMsg instanceof String greetMsg instanceof String
assert greetMsg == "Hello, from a private method!" greetMsg == "Hello, from a private method!"
} }
def 'Should return MissingMethodException when using Employee.greetingMessage method'() { def 'Should return MissingMethodException when using Employee.greetingMessage method'() {
when: when:
def exception
try {
employee.greetingMessage() employee.greetingMessage()
}catch(Exception e) {
exception = e
}
then: then:
exception thrown(MissingMethodException)
exception instanceof groovy.lang.MissingMethodException specificationContext.thrownException.message ==
assert exception.message == "No signature of method: com.baeldung.traits.Employee.greetingMessage()"+ "No signature of method: com.baeldung.traits.Employee.greetingMessage() is applicable for argument types: () values: []"
" is applicable for argument types: () values: []"
} }
def 'Should return employee instance when using Employee.whoAmI method'() { def 'Should return employee instance when using Employee.whoAmI method'() {
when: when:
def emp = employee.self() def emp = employee.self()
then: then:
emp emp
emp instanceof Employee emp instanceof Employee
assert emp.is(employee) emp.is(employee)
} }
def 'Should display lastName when using Employee.showLastName method'() { def 'Should display lastName when using Employee.showLastName method'() {
when: when:
def lastNameMsg = employee.showLastName() def lastNameMsg = employee.showLastName()
then: then:
lastNameMsg lastNameMsg
lastNameMsg instanceof String lastNameMsg instanceof String
assert lastNameMsg == "Hello, Marley!" lastNameMsg == "Hello, Marley!"
} }
def 'Should be able to define properties of UserTrait in Employee instance'() { def 'Should be able to define properties of UserTrait in Employee instance'() {
when: when:
employee = new Employee(email: "a@e.com", address: "baeldung.com") employee = new Employee(email: "a@e.com", address: "baeldung.com")
then: then:
employee employee
employee instanceof Employee employee instanceof Employee
assert employee.email == "a@e.com" employee.email == "a@e.com"
assert employee.address == "baeldung.com" employee.address == "baeldung.com"
} }
def 'Should execute basicAbility method from SpeakingTrait and return msg string'() { def 'Should execute basicAbility method from SpeakingTrait and return msg string'() {
when: when:
def speakMsg = dog.basicAbility() def speakMsg = dog.basicAbility()
then: then:
speakMsg speakMsg
speakMsg instanceof String speakMsg instanceof String
assert speakMsg == "Speaking!!" speakMsg == "Speaking!!"
} }
def 'Should verify multiple inheritance with traits and execute overridden traits method'() { def 'Should verify multiple inheritance with traits and execute overridden traits method'() {
when: when:
def walkSpeakMsg = dog.speakAndWalk() def walkSpeakMsg = dog.speakAndWalk()
println walkSpeakMsg println walkSpeakMsg
then: then:
walkSpeakMsg walkSpeakMsg
walkSpeakMsg instanceof String walkSpeakMsg instanceof String
assert walkSpeakMsg == "Walk and speak!!" walkSpeakMsg == "Walk and speak!!"
} }
def 'Should implement AnimalTrait at runtime and access basicBehavior method'() { def 'Should implement AnimalTrait at runtime and access basicBehavior method'() {
when: when:
def dogInstance = new Dog() as AnimalTrait def dogInstance = new Dog() as AnimalTrait
def basicBehaviorMsg = dogInstance.basicBehavior() def basicBehaviorMsg = dogInstance.basicBehavior()
then: then:
basicBehaviorMsg basicBehaviorMsg
basicBehaviorMsg instanceof String basicBehaviorMsg instanceof String
assert basicBehaviorMsg == "Animalistic!!" basicBehaviorMsg == "Animalistic!!"
} }
} }

View File

@ -21,11 +21,11 @@
</modules> </modules>
<properties> <properties>
<groovy.version>2.5.7</groovy.version> <groovy.version>3.0.8</groovy.version>
<groovy-all.version>2.5.6</groovy-all.version> <groovy-all.version>3.0.8</groovy-all.version>
<groovy-sql.version>2.5.6</groovy-sql.version> <groovy-sql.version>3.0.8</groovy-sql.version>
<hsqldb.version>2.4.0</hsqldb.version> <hsqldb.version>2.4.0</hsqldb.version>
<spock-core.version>1.1-groovy-2.4</spock-core.version> <spock-core.version>2.3-groovy-3.0</spock-core.version>
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version> <gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
</properties> </properties>

View File

@ -0,0 +1,40 @@
package com.baeldung.java8to17;
public class Address {
private String street;
private String city;
private String pin;
public Address(String street, String city, String pin) {
super();
this.street = street;
this.city = city;
this.pin = pin;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getPin() {
return pin;
}
public void setPin(String pin) {
this.pin = pin;
}
}

View File

@ -0,0 +1,4 @@
package com.baeldung.java8to17;
public record Circle(double radius) implements Shape {
}

View File

@ -0,0 +1,30 @@
package com.baeldung.java8to17;
public class Person {
private String name;
private Address address;
public Person(String name, Address address) {
super();
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}

View File

@ -0,0 +1,4 @@
package com.baeldung.java8to17;
public record Rectangle(double length, double width) implements Shape {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.java8to17;
public interface Shape {
}

View File

@ -0,0 +1,5 @@
package com.baeldung.java8to17;
public record Student(int rollNo, String name) {
}

View File

@ -0,0 +1,87 @@
package com.baeldung.java17;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertThrows;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import com.baeldung.java8to17.Address;
import com.baeldung.java8to17.Circle;
import com.baeldung.java8to17.Person;
import com.baeldung.java8to17.Rectangle;
import com.baeldung.java8to17.Student;
public class Java8to17ExampleUnitTest {
@Test
void givenMultiLineText_whenUsingTextBlock_thenStringIsReturned() {
String value = """
This is a
Multi-line
Text
""";
assertThat(value).isEqualTo("This is a\nMulti-line\nText\n");
}
@Test
void givenString_whenUsingUtilFunctions_thenReturnsExpectedResult() {
assertThat(" ".isBlank());
assertThat("Twinkle ".repeat(2)).isEqualTo("Twinkle Twinkle ");
assertThat("Format Line".indent(4)).isEqualTo(" Format Line\n");
assertThat("Line 1 \n Line2".lines()).asList().size().isEqualTo(2);
assertThat(" Text with white spaces ".strip()).isEqualTo("Text with white spaces");
assertThat("Car, Bus, Train".transform(s1 -> Arrays.asList(s1.split(","))).get(0)).isEqualTo("Car");
}
@Test
void givenDataModel_whenUsingRecordType_thenBehavesLikeDTO() {
Student student = new Student(10, "Priya");
Student student2 = new Student(10, "Priya");
assertThat(student.rollNo()).isEqualTo(10);
assertThat(student.name()).isEqualTo("Priya");
assertThat(student.equals(student2));
assertThat(student.hashCode()).isEqualTo(student2.hashCode());
}
@Test
void givenObject_whenThrowingNPE_thenReturnsHelpfulMessage() {
Person student = new Person("Lakshmi", new Address("35, West Street", null, null));
Exception exception = assertThrows(NullPointerException.class, () -> {
student.getAddress().getCity().toLowerCase();
});
assertThat(exception.getMessage()).isEqualTo(
"Cannot invoke \"String.toLowerCase()\" because the return value of \"com.baeldung.java8to17.Address.getCity()\" is null");
}
@Test
void givenGenericObject_whenUsingPatternMatching_thenReturnsTargetType() {
String city = null;
Object obj = new Address("35, West Street", "Chennai", "6000041");
if (obj instanceof Address address) {
city = address.getCity();
}
assertThat(city).isEqualTo("Chennai");
}
@Test
void givenGenericObject_whenUsingSwitchExpression_thenPatternMatchesRightObject() {
Object shape = new Rectangle(10, 20);
double circumference = switch (shape) {
case Rectangle r -> 2 * r.length() + 2 * r.width();
case Circle c -> 2 * c.radius() * Math.PI;
default -> throw new IllegalArgumentException("Unknown shape");
};
assertThat(circumference).isEqualTo(60);
}
}

View File

@ -48,7 +48,7 @@ class AESUtilUnitTest implements WithAssertions {
IvParameterSpec ivParameterSpec = AESUtil.generateIv(); IvParameterSpec ivParameterSpec = AESUtil.generateIv();
File inputFile = Paths.get("src/test/resources/baeldung.txt") File inputFile = Paths.get("src/test/resources/baeldung.txt")
.toFile(); .toFile();
File encryptedFile = new File("classpath:baeldung.encrypted"); File encryptedFile = new File("baeldung.encrypted");
File decryptedFile = new File("document.decrypted"); File decryptedFile = new File("document.decrypted");
// when // when
@ -57,8 +57,8 @@ class AESUtilUnitTest implements WithAssertions {
// then // then
assertThat(inputFile).hasSameTextualContentAs(decryptedFile); assertThat(inputFile).hasSameTextualContentAs(decryptedFile);
encryptedFile.delete(); encryptedFile.deleteOnExit();
decryptedFile.delete(); decryptedFile.deleteOnExit();
} }
@Test @Test

View File

@ -10,3 +10,4 @@
- [Merging java.util.Properties Objects](https://www.baeldung.com/java-merging-properties) - [Merging java.util.Properties Objects](https://www.baeldung.com/java-merging-properties)
- [Illegal Character Compilation Error](https://www.baeldung.com/java-illegal-character-error) - [Illegal Character Compilation Error](https://www.baeldung.com/java-illegal-character-error)
- [Lambda Expression vs. Anonymous Inner Class](https://www.baeldung.com/java-lambdas-vs-anonymous-class) - [Lambda Expression vs. Anonymous Inner Class](https://www.baeldung.com/java-lambdas-vs-anonymous-class)
- [Difference Between Class.forName() and Class.forName().newInstance()](https://www.baeldung.com/java-class-forname-vs-class-forname-newinstance)

View File

@ -44,10 +44,10 @@
</build> </build>
<properties> <properties>
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.10.0</maven-compiler-plugin.version>
<pmdVersion>6.0.1</pmdVersion> <pmdVersion>6.53.0</pmdVersion>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>11</maven.compiler.target>
</properties> </properties>
</project> </project>

View File

@ -18,8 +18,9 @@ public class UnitTestNamingConventionRule extends AbstractJavaRule {
"UnitTest", "UnitTest",
"jmhTest"); "jmhTest");
@Override
public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
String className = node.getImage(); String className = node.getSimpleName();
Objects.requireNonNull(className); Objects.requireNonNull(className);
if (className.endsWith("SpringContextTest")) { if (className.endsWith("SpringContextTest")) {

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-exclusions</artifactId>
<version>0.0.0-SNAPSHOT</version>
<name>core-java-exclusions</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.dependency-exclusion</groupId>
<artifactId>dependency-exclusion</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-version}</version>
<configuration>
<runOrder>alphabetical</runOrder>
<threadCount>1</threadCount>
<properties>
<property>
<name>junit</name>
<value>false</value>
</property>
</properties>
</configuration>
<dependencies>
<dependency>
<!-- Deactivate JUnit 4.7 engine by overriding it with an empty dummy -->
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>dummy</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,12 @@
package com.sample.project.tests;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class ExcludeDirectDependencyUnitTest {
@Test
public void basicUnitTest() {
assertTrue(true);
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>dummy</version>
</project>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.dependency-exclusion</groupId>
<artifactId>dependency-exclusion</artifactId>
<name>dependency-exclusion</name>
<packaging>pom</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-java</relativePath>
</parent>
<properties>
<surefire-version>2.22.2</surefire-version>
</properties>
<modules>
<module>dummy-surefire-junit47</module>
<module>core-java-exclusions</module>
</modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-version}</version>
<configuration>
<threadCount>1</threadCount>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit-platform</artifactId>
<version>${surefire-version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -7,3 +7,8 @@ This module contains articles about Feign
- [Intro to Feign](https://www.baeldung.com/intro-to-feign) - [Intro to Feign](https://www.baeldung.com/intro-to-feign)
- [Retrying Feign Calls](https://www.baeldung.com/feign-retry) - [Retrying Feign Calls](https://www.baeldung.com/feign-retry)
- [Setting Request Headers Using Feign](https://www.baeldung.com/java-feign-request-headers) - [Setting Request Headers Using Feign](https://www.baeldung.com/java-feign-request-headers)
- [File Upload With Open Feign](https://www.baeldung.com/java-feign-file-upload)
- [Feign Logging Configuration](https://www.baeldung.com/java-feign-logging)
- [Retrieve Original Message From Feign ErrorDecoder](https://www.baeldung.com/feign-retrieve-original-message)
- [RequestLine with Feign Client](https://www.baeldung.com/feign-requestline)
- [Propagating Exceptions With OpenFeign and Spring](https://www.baeldung.com/spring-openfeign-propagate-exception)

View File

@ -64,6 +64,22 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>${feign.form.spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${spring.cloud.openfeign.version}</version>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>${wire.mock.version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -118,6 +134,9 @@
<properties> <properties>
<feign.version>11.8</feign.version> <feign.version>11.8</feign.version>
<wsdl4j.version>1.6.3</wsdl4j.version> <wsdl4j.version>1.6.3</wsdl4j.version>
<feign.form.spring.version>3.8.0</feign.form.spring.version>
<spring.cloud.openfeign.version>3.1.2</spring.cloud.openfeign.version>
<wire.mock.version>2.33.2</wire.mock.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,16 @@
package com.baeldung.core;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}

View File

@ -1,6 +1,7 @@
package com.baeldung.cloud.openfeign.client; package com.baeldung.core.client;
import com.baeldung.core.model.Employee;
import com.baeldung.cloud.openfeign.model.Employee;
import feign.Headers; import feign.Headers;
import feign.Param; import feign.Param;
import feign.RequestLine; import feign.RequestLine;

View File

@ -0,0 +1,13 @@
package com.baeldung.core.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import com.baeldung.core.config.FeignConfig;
@FeignClient(name = "user-client", url="https://jsonplaceholder.typicode.com", configuration = FeignConfig.class)
public interface UserClient {
@GetMapping(value = "/users")
String getUsers();
}

View File

@ -1,7 +1,8 @@
package com.baeldung.cloud.openfeign.config; package com.baeldung.core.config;
import org.springframework.context.annotation.Bean;
import feign.Logger; import feign.Logger;
import org.springframework.context.annotation.Bean;
public class FeignConfig { public class FeignConfig {

View File

@ -1,13 +1,15 @@
package com.baeldung.cloud.openfeign.controller; package com.baeldung.core.controller;
import com.baeldung.cloud.openfeign.client.EmployeeClient;
import com.baeldung.cloud.openfeign.model.Employee;
import feign.Feign;
import feign.form.spring.SpringFormEncoder;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.baeldung.core.client.EmployeeClient;
import com.baeldung.core.model.Employee;
import feign.Feign;
import feign.form.spring.SpringFormEncoder;
@RestController @RestController
public class EmployeeController { public class EmployeeController {

View File

@ -1,13 +1,13 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.client; package com.baeldung.core.customizederrorhandling.client;
import com.baeldung.cloud.openfeign.customizederrorhandling.config.FeignConfig;
import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import com.baeldung.core.customizederrorhandling.config.FeignConfig;
import com.baeldung.core.defaulterrorhandling.model.Product;
@FeignClient(name = "product-client-2", url = "http://localhost:8081/product/", configuration = FeignConfig.class) @FeignClient(name = "product-client-2", url = "http://localhost:8081/product/", configuration = FeignConfig.class)
public interface ProductClient { public interface ProductClient {

View File

@ -1,8 +1,9 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.config; package com.baeldung.core.customizederrorhandling.config;
import com.baeldung.core.customizederrorhandling.exception.ProductNotFoundException;
import com.baeldung.core.customizederrorhandling.exception.ProductServiceNotAvailableException;
import com.baeldung.core.exception.BadRequestException;
import com.baeldung.cloud.openfeign.exception.BadRequestException;
import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ProductNotFoundException;
import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ProductServiceNotAvailableException;
import feign.Response; import feign.Response;
import feign.codec.ErrorDecoder; import feign.codec.ErrorDecoder;

View File

@ -1,8 +1,9 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.config; package com.baeldung.core.customizederrorhandling.config;
import org.springframework.context.annotation.Bean;
import feign.Logger; import feign.Logger;
import feign.codec.ErrorDecoder; import feign.codec.ErrorDecoder;
import org.springframework.context.annotation.Bean;
public class FeignConfig { public class FeignConfig {

View File

@ -1,12 +1,13 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.controller; package com.baeldung.core.customizederrorhandling.controller;
import com.baeldung.cloud.openfeign.customizederrorhandling.client.ProductClient;
import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.core.customizederrorhandling.client.ProductClient;
import com.baeldung.core.defaulterrorhandling.model.Product;
@RestController("product_controller2") @RestController("product_controller2")
@RequestMapping(value = "myapp2") @RequestMapping(value = "myapp2")

View File

@ -1,10 +1,11 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.exception; package com.baeldung.core.customizederrorhandling.exception;
import java.util.Date;
import org.springframework.http.HttpStatus;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.http.HttpStatus;
import java.util.Date;
public class ErrorResponse { public class ErrorResponse {

View File

@ -1,6 +1,5 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.exception; package com.baeldung.core.customizederrorhandling.exception;
import com.baeldung.cloud.openfeign.exception.BadRequestException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.exception; package com.baeldung.core.customizederrorhandling.exception;
public class ProductNotFoundException extends RuntimeException { public class ProductNotFoundException extends RuntimeException {

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.exception; package com.baeldung.core.customizederrorhandling.exception;
public class ProductServiceNotAvailableException extends RuntimeException { public class ProductServiceNotAvailableException extends RuntimeException {

View File

@ -1,13 +1,13 @@
package com.baeldung.cloud.openfeign.defaulterrorhandling.client; package com.baeldung.core.defaulterrorhandling.client;
import com.baeldung.cloud.openfeign.defaulterrorhandling.config.FeignConfig;
import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import com.baeldung.core.defaulterrorhandling.config.FeignConfig;
import com.baeldung.core.defaulterrorhandling.model.Product;
@FeignClient(name = "product-client", url = "http://localhost:8084/product/", configuration = FeignConfig.class) @FeignClient(name = "product-client", url = "http://localhost:8084/product/", configuration = FeignConfig.class)
public interface ProductClient { public interface ProductClient {

View File

@ -1,7 +1,8 @@
package com.baeldung.cloud.openfeign.defaulterrorhandling.config; package com.baeldung.core.defaulterrorhandling.config;
import org.springframework.context.annotation.Bean;
import feign.Logger; import feign.Logger;
import org.springframework.context.annotation.Bean;
public class FeignConfig { public class FeignConfig {

View File

@ -1,10 +1,13 @@
package com.baeldung.cloud.openfeign.defaulterrorhandling.controller; package com.baeldung.core.defaulterrorhandling.controller;
import com.baeldung.cloud.openfeign.defaulterrorhandling.client.ProductClient;
import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.core.defaulterrorhandling.client.ProductClient;
import com.baeldung.core.defaulterrorhandling.model.Product;
@RestController("product_controller1") @RestController("product_controller1")
@RequestMapping(value ="myapp1") @RequestMapping(value ="myapp1")

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.defaulterrorhandling.model; package com.baeldung.core.defaulterrorhandling.model;
public class Product { public class Product {

View File

@ -0,0 +1,21 @@
package com.baeldung.core.exception;
public class BadRequestException extends Exception {
public BadRequestException() {
}
public BadRequestException(String message) {
super(message);
}
public BadRequestException(Throwable cause) {
super(cause);
}
@Override
public String toString() {
return "BadRequestException: "+getMessage();
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.core.exception;
public class NotFoundException extends Exception {
public NotFoundException(String message) {
super(message);
}
public NotFoundException(Throwable cause) {
super(cause);
}
@Override
public String toString() {
return "NotFoundException: " + getMessage();
}
}

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.fileupload.config; package com.baeldung.core.fileupload.config;
public class ExceptionMessage { public class ExceptionMessage {
private String timestamp; private String timestamp;

View File

@ -1,6 +1,5 @@
package com.baeldung.cloud.openfeign.fileupload.config; package com.baeldung.core.fileupload.config;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -13,12 +12,7 @@ import feign.form.spring.SpringFormEncoder;
public class FeignSupportConfig { public class FeignSupportConfig {
@Bean @Bean
public Encoder multipartFormEncoder() { public Encoder multipartFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(new ObjectFactory<HttpMessageConverters>() { return new SpringFormEncoder(new SpringEncoder(() -> new HttpMessageConverters(new RestTemplate().getMessageConverters())));
@Override
public HttpMessageConverters getObject() {
return new HttpMessageConverters(new RestTemplate().getMessageConverters());
}
}));
} }
@Bean @Bean

View File

@ -1,10 +1,10 @@
package com.baeldung.cloud.openfeign.fileupload.config; package com.baeldung.core.fileupload.config;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import com.baeldung.cloud.openfeign.exception.BadRequestException; import com.baeldung.core.exception.BadRequestException;
import com.baeldung.cloud.openfeign.exception.NotFoundException; import com.baeldung.core.exception.NotFoundException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Response; import feign.Response;
@ -15,7 +15,7 @@ public class RetreiveMessageErrorDecoder implements ErrorDecoder {
@Override @Override
public Exception decode(String methodKey, Response response) { public Exception decode(String methodKey, Response response) {
ExceptionMessage message = null; ExceptionMessage message;
try (InputStream bodyIs = response.body() try (InputStream bodyIs = response.body()
.asInputStream()) { .asInputStream()) {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.fileupload.controller; package com.baeldung.core.fileupload.controller;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.baeldung.cloud.openfeign.fileupload.service.UploadService; import com.baeldung.core.fileupload.service.UploadService;
@RestController @RestController
public class FileController { public class FileController {

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.fileupload.service; package com.baeldung.core.fileupload.service;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.baeldung.cloud.openfeign.fileupload.config.FeignSupportConfig; import com.baeldung.core.fileupload.config.FeignSupportConfig;
@FeignClient(name = "file", url = "http://localhost:8081", configuration = FeignSupportConfig.class) @FeignClient(name = "file", url = "http://localhost:8081", configuration = FeignSupportConfig.class)
public interface UploadClient { public interface UploadClient {

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.fileupload.service; package com.baeldung.core.fileupload.service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.fileupload.service; package com.baeldung.core.fileupload.service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign.model; package com.baeldung.core.model;
public class Employee { public class Employee {

View File

@ -5,3 +5,5 @@ ws.port.type.name=UsersPort
ws.target.namespace=http://www.baeldung.com/springbootsoap/feignclient ws.target.namespace=http://www.baeldung.com/springbootsoap/feignclient
ws.location.uri=http://localhost:${server.port}/ws/users/ ws.location.uri=http://localhost:${server.port}/ws/users/
debug=false debug=false
logging.level.com.baeldung.core=DEBUG

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
<logger name="feign.Logger" level="DEBUG" />
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOGS" value="./logs" />
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</layout>
</appender>
<appender name="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/spring-boot-logger.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- LOG everything at INFO level -->
<root level="info">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</root>
<!-- LOG "com.baeldung*" at TRACE level -->
<logger name="com.baeldung" level="trace" additivity="false">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</logger>
</configuration>

View File

@ -1,4 +1,4 @@
package com.baeldung.cloud.openfeign; package com.baeldung.core;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -14,10 +14,10 @@ import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.baeldung.cloud.openfeign.fileupload.service.UploadService; import com.baeldung.core.fileupload.service.UploadService;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest @SpringBootTest(classes = ExampleApplication.class)
public class OpenFeignFileUploadLiveTest { public class OpenFeignFileUploadLiveTest {
@Autowired @Autowired

View File

@ -1,8 +1,12 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.client; package com.baeldung.core.customizederrorhandling.client;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.junit.Assert.assertThrows;
import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ProductNotFoundException;
import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ProductServiceNotAvailableException;
import com.github.tomakehurst.wiremock.WireMockServer;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -11,11 +15,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import static com.github.tomakehurst.wiremock.client.WireMock.*; import com.baeldung.core.ExampleApplication;
import static org.junit.Assert.assertThrows; import com.baeldung.core.customizederrorhandling.exception.ProductNotFoundException;
import com.baeldung.core.customizederrorhandling.exception.ProductServiceNotAvailableException;
import com.github.tomakehurst.wiremock.WireMockServer;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest @SpringBootTest(classes = ExampleApplication.class)
public class ProductClientUnitTest { public class ProductClientUnitTest {
@Autowired @Autowired

View File

@ -1,10 +1,13 @@
package com.baeldung.cloud.openfeign.customizederrorhandling.controller; package com.baeldung.core.customizederrorhandling.controller;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import com.baeldung.cloud.openfeign.customizederrorhandling.client.ProductClient;
import com.baeldung.cloud.openfeign.customizederrorhandling.exception.ErrorResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -18,10 +21,11 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import static com.github.tomakehurst.wiremock.client.WireMock.*; import com.baeldung.core.customizederrorhandling.client.ProductClient;
import static org.junit.Assert.assertEquals; import com.baeldung.core.customizederrorhandling.exception.ErrorResponse;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import com.fasterxml.jackson.databind.ObjectMapper;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)

View File

@ -1,8 +1,13 @@
package com.baeldung.cloud.openfeign.defaulterrorhandling.client; package com.baeldung.core.defaulterrorhandling.client;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import com.baeldung.cloud.openfeign.defaulterrorhandling.model.Product;
import com.github.tomakehurst.wiremock.WireMockServer;
import feign.FeignException;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -12,12 +17,14 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import static com.github.tomakehurst.wiremock.client.WireMock.*; import com.baeldung.core.ExampleApplication;
import static org.junit.Assert.assertEquals; import com.baeldung.core.defaulterrorhandling.model.Product;
import static org.junit.Assert.assertThrows; import com.github.tomakehurst.wiremock.WireMockServer;
import feign.FeignException;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest @SpringBootTest(classes = ExampleApplication.class)
public class ProductClientUnitTest { public class ProductClientUnitTest {
@Autowired @Autowired

View File

@ -1,8 +1,13 @@
package com.baeldung.cloud.openfeign.defaulterrorhandling.controller; package com.baeldung.core.defaulterrorhandling.controller;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.configureFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import com.baeldung.cloud.openfeign.defaulterrorhandling.client.ProductClient;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -16,10 +21,9 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static com.github.tomakehurst.wiremock.client.WireMock.*; import com.baeldung.core.defaulterrorhandling.client.ProductClient;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import com.github.tomakehurst.wiremock.WireMockServer;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.github.tomakehurst.wiremock.client.WireMock;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@WebMvcTest(ProductController.class) @WebMvcTest(ProductController.class)

View File

@ -1,11 +1,12 @@
package com.baeldung.cloud.openfeign.defaulterrorhandling.controller; package com.baeldung.core.defaulterrorhandling.controller;
import feign.FeignException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import feign.FeignException;
@RestControllerAdvice @RestControllerAdvice
public class TestControllerAdvice { public class TestControllerAdvice {

View File

@ -0,0 +1,86 @@
package com.baeldung.digitalsignature;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.DigestInfo;
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.Certificate;
import java.util.Arrays;
public class DigitalSignatureUtils {
public static PrivateKey getPrivateKey(String file, char[] password, String storeType, String alias) throws Exception {
KeyStore keyStore = KeyStore.getInstance(storeType);
keyStore.load(new FileInputStream(file), password);
return (PrivateKey) keyStore.getKey(alias, password);
}
public static PublicKey getPublicKey(String file, char[] password, String storeType, String alias) throws Exception {
KeyStore keyStore = KeyStore.getInstance(storeType);
keyStore.load(new FileInputStream(file), password);
Certificate certificate = keyStore.getCertificate(alias);
return certificate.getPublicKey();
}
public static byte[] sign(byte[] message, String signingAlgorithm, PrivateKey signingKey) throws SecurityException {
try {
Signature signature = Signature.getInstance(signingAlgorithm);
signature.initSign(signingKey);
signature.update(message);
return signature.sign();
} catch (GeneralSecurityException exp) {
throw new SecurityException("Error during signature generation", exp);
}
}
public static boolean verify(byte[] messageBytes, String signingAlgorithm, PublicKey publicKey, byte[] signedData) {
try {
Signature signature = Signature.getInstance(signingAlgorithm);
signature.initVerify(publicKey);
signature.update(messageBytes);
return signature.verify(signedData);
} catch (GeneralSecurityException exp) {
throw new SecurityException("Error during verifying", exp);
}
}
public static byte[] signWithMessageDigestAndCipher(byte[] messageBytes, String hashingAlgorithm, PrivateKey privateKey) {
try {
MessageDigest md = MessageDigest.getInstance(hashingAlgorithm);
byte[] messageHash = md.digest(messageBytes);
DigestAlgorithmIdentifierFinder hashAlgorithmFinder = new DefaultDigestAlgorithmIdentifierFinder();
AlgorithmIdentifier hashingAlgorithmIdentifier = hashAlgorithmFinder.find(hashingAlgorithm);
DigestInfo digestInfo = new DigestInfo(hashingAlgorithmIdentifier, messageHash);
byte[] hashToEncrypt = digestInfo.getEncoded();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(hashToEncrypt);
} catch (GeneralSecurityException | IOException exp) {
throw new SecurityException("Error during signature generation", exp);
}
}
public static boolean verifyWithMessageDigestAndCipher(byte[] messageBytes, String hashingAlgorithm, PublicKey publicKey, byte[] encryptedMessageHash) {
try {
MessageDigest md = MessageDigest.getInstance(hashingAlgorithm);
byte[] newMessageHash = md.digest(messageBytes);
DigestAlgorithmIdentifierFinder hashAlgorithmFinder = new DefaultDigestAlgorithmIdentifierFinder();
AlgorithmIdentifier hashingAlgorithmIdentifier = hashAlgorithmFinder.find(hashingAlgorithm);
DigestInfo digestInfo = new DigestInfo(hashingAlgorithmIdentifier, newMessageHash);
byte[] hashToEncrypt = digestInfo.getEncoded();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] decryptedMessageHash = cipher.doFinal(encryptedMessageHash);
return Arrays.equals(decryptedMessageHash, hashToEncrypt);
} catch (GeneralSecurityException | IOException exp) {
throw new SecurityException("Error during verifying", exp);
}
}
}

Some files were not shown because too many files have changed in this diff Show More