diff --git a/apache-zookeeper/pom.xml b/apache-zookeeper/pom.xml
index 3a6fc1787b..b08da534a5 100644
--- a/apache-zookeeper/pom.xml
+++ b/apache-zookeeper/pom.xml
@@ -1,36 +1,23 @@
- 4.0.0
- com.baeldung
- apache-zookeeper
- 0.0.1-SNAPSHOT
- jar
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
+ com.baeldung
+ apache-zookeeper
+ 0.0.1-SNAPSHOT
+ jar
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
- org.apache.zookeeper
- zookeeper
- 3.3.2
-
-
- com.sun.jmx
- jmxri
-
-
- com.sun.jdmk
- jmxtools
-
-
- javax.jms
- jms
-
-
-
-
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.apache.zookeeper
+ zookeeper
+ 3.4.11
+
+
+
diff --git a/aws/pom.xml b/aws/pom.xml
index c66c420fae..33fc3b0cba 100644
--- a/aws/pom.xml
+++ b/aws/pom.xml
@@ -18,7 +18,7 @@
1.3.0
1.1.0
2.8.0
- 1.11.154
+ 1.11.290
4.12
2.8.9
3.8.0
diff --git a/aws/src/main/java/com/baeldung/s3/MultipartUpload.java b/aws/src/main/java/com/baeldung/s3/MultipartUpload.java
new file mode 100644
index 0000000000..711046c112
--- /dev/null
+++ b/aws/src/main/java/com/baeldung/s3/MultipartUpload.java
@@ -0,0 +1,56 @@
+package com.baeldung.s3;
+
+import com.amazonaws.AmazonClientException;
+import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
+import com.amazonaws.event.ProgressListener;
+import com.amazonaws.regions.Regions;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3ClientBuilder;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+import com.amazonaws.services.s3.transfer.TransferManager;
+import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
+import com.amazonaws.services.s3.transfer.Upload;
+
+import java.io.File;
+import java.util.concurrent.Executors;
+
+public class MultipartUpload {
+
+ public static void main(String[] args) throws Exception {
+ String existingBucketName = "baeldung-bucket";
+ String keyName = "my-picture.jpg";
+ String filePath = "documents/my-picture.jpg";
+
+ AmazonS3 amazonS3 = AmazonS3ClientBuilder
+ .standard()
+ .withCredentials(new DefaultAWSCredentialsProviderChain())
+ .withRegion(Regions.DEFAULT_REGION)
+ .build();
+
+ int maxUploadThreads = 5;
+
+ TransferManager tm = TransferManagerBuilder
+ .standard()
+ .withS3Client(amazonS3)
+ .withMultipartUploadThreshold((long) (5 * 1024 * 1024))
+ .withExecutorFactory(() -> Executors.newFixedThreadPool(maxUploadThreads))
+ .build();
+
+ ProgressListener progressListener =
+ progressEvent -> System.out.println("Transferred bytes: " + progressEvent.getBytesTransferred());
+
+ PutObjectRequest request = new PutObjectRequest(existingBucketName, keyName, new File(filePath));
+
+ request.setGeneralProgressListener(progressListener);
+
+ Upload upload = tm.upload(request);
+
+ try {
+ upload.waitForCompletion();
+ System.out.println("Upload complete.");
+ } catch (AmazonClientException e) {
+ System.out.println("Error occurred while uploading file");
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/aws/src/test/java/com/baeldung/s3/MultipartUploadTest.java b/aws/src/test/java/com/baeldung/s3/MultipartUploadTest.java
new file mode 100644
index 0000000000..bc8d517a0e
--- /dev/null
+++ b/aws/src/test/java/com/baeldung/s3/MultipartUploadTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.s3;
+
+import com.amazonaws.event.ProgressListener;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+import com.amazonaws.services.s3.model.PutObjectResult;
+import com.amazonaws.services.s3.transfer.TransferManager;
+import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
+import com.amazonaws.services.s3.transfer.Upload;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.concurrent.Executors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class MultipartUploadTest {
+
+ private static final String BUCKET_NAME = "bucket_name";
+ private static final String KEY_NAME = "picture.jpg";
+
+ private AmazonS3 amazonS3;
+ private TransferManager tm;
+ private ProgressListener progressListener;
+
+ @Before
+ public void setup() {
+ amazonS3 = mock(AmazonS3.class);
+ tm = TransferManagerBuilder
+ .standard()
+ .withS3Client(amazonS3)
+ .withMultipartUploadThreshold((long) (5 * 1024 * 1025))
+ .withExecutorFactory(() -> Executors.newFixedThreadPool(5))
+ .build();
+ progressListener =
+ progressEvent -> System.out.println("Transferred bytes: " + progressEvent.getBytesTransferred());
+ }
+
+ @Test
+ public void whenUploadingFileWithTransferManager_thenVerifyUploadRequested() {
+ File file = mock(File.class);
+ PutObjectResult s3Result = mock(PutObjectResult.class);
+
+ when(amazonS3.putObject(anyString(), anyString(), (File) any())).thenReturn(s3Result);
+ when(file.getName()).thenReturn(KEY_NAME);
+
+ PutObjectRequest request = new PutObjectRequest(BUCKET_NAME, KEY_NAME, file);
+ request.setGeneralProgressListener(progressListener);
+
+ Upload upload = tm.upload(request);
+
+ assertThat(upload).isNotNull();
+ verify(amazonS3).putObject(request);
+ }
+}
diff --git a/core-java/src/main/resources/META-INF/services/com.sun.source.util.Plugin b/core-java-sun/src/main/resources/META-INF/services/com.sun.source.util.Plugin
similarity index 100%
rename from core-java/src/main/resources/META-INF/services/com.sun.source.util.Plugin
rename to core-java-sun/src/main/resources/META-INF/services/com.sun.source.util.Plugin
diff --git a/core-java/src/main/java/com/baeldung/externalizable/Community.java b/core-java/src/main/java/com/baeldung/externalizable/Community.java
new file mode 100644
index 0000000000..bdbec9f547
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/externalizable/Community.java
@@ -0,0 +1,23 @@
+package com.baeldung.externalizable;
+
+import java.io.*;
+
+public class Community implements Serializable {
+
+ private int id;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return "Community{" +
+ "id=" + id +
+ '}';
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/externalizable/Country.java b/core-java/src/main/java/com/baeldung/externalizable/Country.java
new file mode 100644
index 0000000000..9fa95002f5
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/externalizable/Country.java
@@ -0,0 +1,62 @@
+package com.baeldung.externalizable;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+public class Country implements Externalizable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String name;
+ private String capital;
+ private int code;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCapital() {
+ return capital;
+ }
+
+ public void setCapital(String capital) {
+ this.capital = capital;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeUTF(name);
+ out.writeUTF(capital);
+ out.writeInt(code);
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ this.name = in.readUTF();
+ this.capital = in.readUTF();
+ this.code = in.readInt();
+ }
+
+ @Override
+ public String toString() {
+ return "Country{" +
+ "name='" + name + '\'' +
+ ", capital='" + capital + '\'' +
+ ", code=" + code +
+ '}';
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/externalizable/Region.java b/core-java/src/main/java/com/baeldung/externalizable/Region.java
new file mode 100644
index 0000000000..3ddb694291
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/externalizable/Region.java
@@ -0,0 +1,57 @@
+package com.baeldung.externalizable;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+public class Region extends Country implements Externalizable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String climate;
+ private Double population;
+ private Community community;
+
+ public String getClimate() {
+ return climate;
+ }
+
+ public void setClimate(String climate) {
+ this.climate = climate;
+ }
+
+ public Double getPopulation() {
+ return population;
+ }
+
+ public void setPopulation(Double population) {
+ this.population = population;
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+ out.writeUTF(climate);
+ community = new Community();
+ community.setId(5);
+ out.writeObject(community);
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+ this.climate = in.readUTF();
+ community = (Community) in.readObject();
+ }
+
+ @Override
+ public String toString() {
+ return "Region = {" +
+ "country='" + super.toString() + '\'' +
+ "community='" + community.toString() + '\'' +
+ "climate='" + climate + '\'' +
+ ", population=" + population +
+ '}';
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java b/core-java/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java
new file mode 100644
index 0000000000..651364fb13
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/externalizable/ExternalizableUnitTest.java
@@ -0,0 +1,71 @@
+package com.baeldung.externalizable;
+
+import org.junit.Test;
+
+import java.io.*;
+
+import static org.junit.Assert.assertTrue;
+
+public class ExternalizableUnitTest {
+
+ private final static String OUTPUT_FILE = "externalizable.txt";
+
+ @Test
+ public void whenSerializing_thenUseExternalizable() throws IOException, ClassNotFoundException {
+
+ Country c = new Country();
+ c.setCapital("Yerevan");
+ c.setCode(374);
+ c.setName("Armenia");
+
+ FileOutputStream fileOutputStream = new FileOutputStream(OUTPUT_FILE);
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
+ c.writeExternal(objectOutputStream);
+
+ objectOutputStream.flush();
+ objectOutputStream.close();
+ fileOutputStream.close();
+
+ FileInputStream fileInputStream = new FileInputStream(OUTPUT_FILE);
+ ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
+
+ Country c2 = new Country();
+ c2.readExternal(objectInputStream);
+
+ objectInputStream.close();
+ fileInputStream.close();
+
+ assertTrue(c2.getCode() == c.getCode());
+ assertTrue(c2.getName().equals(c.getName()));
+ }
+
+ @Test
+ public void whenInheritanceSerialization_then_UseExternalizable() throws IOException, ClassNotFoundException {
+
+ Region r = new Region();
+ r.setCapital("Yerevan");
+ r.setCode(374);
+ r.setName("Armenia");
+ r.setClimate("Mediterranean");
+ r.setPopulation(120.000);
+
+ FileOutputStream fileOutputStream = new FileOutputStream(OUTPUT_FILE);
+ ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
+ r.writeExternal(objectOutputStream);
+
+ objectOutputStream.flush();
+ objectOutputStream.close();
+ fileOutputStream.close();
+
+ FileInputStream fileInputStream = new FileInputStream(OUTPUT_FILE);
+ ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
+
+ Region r2 = new Region();
+ r2.readExternal(objectInputStream);
+
+ objectInputStream.close();
+ fileInputStream.close();
+
+ assertTrue(r2.getPopulation() == null);
+ }
+}
diff --git a/flips/README.md b/flips/README.md
new file mode 100644
index 0000000000..0c62173b6a
--- /dev/null
+++ b/flips/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Guide to Flips For Spring](http://www.baeldung.com/guide-to-flips-for-spring/)
diff --git a/flips/pom.xml b/flips/pom.xml
new file mode 100644
index 0000000000..ecc2af4a47
--- /dev/null
+++ b/flips/pom.xml
@@ -0,0 +1,65 @@
+
+ 4.0.0
+
+ flips
+ flips
+ 0.0.1-SNAPSHOT
+ jar
+
+ flips
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ 1.5.10.RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ 1.5.9.RELEASE
+
+
+
+ com.github.feature-flip
+ flips-web
+ 1.0.1
+
+
+
+ org.projectlombok
+ lombok
+
+ 1.16.18
+ provided
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/flips/src/main/java/com/baeldung/flips/ApplicationConfig.java b/flips/src/main/java/com/baeldung/flips/ApplicationConfig.java
new file mode 100644
index 0000000000..7001aeb991
--- /dev/null
+++ b/flips/src/main/java/com/baeldung/flips/ApplicationConfig.java
@@ -0,0 +1,15 @@
+package com.baeldung.flips;
+
+import org.flips.describe.config.FlipWebContextConfiguration;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Import;
+
+@SpringBootApplication
+@Import(FlipWebContextConfiguration.class)
+public class ApplicationConfig {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ApplicationConfig.class, args);
+ }
+}
\ No newline at end of file
diff --git a/flips/src/main/java/com/baeldung/flips/controller/FlipController.java b/flips/src/main/java/com/baeldung/flips/controller/FlipController.java
new file mode 100644
index 0000000000..50458023b3
--- /dev/null
+++ b/flips/src/main/java/com/baeldung/flips/controller/FlipController.java
@@ -0,0 +1,65 @@
+package com.baeldung.flips.controller;
+
+import com.baeldung.flips.model.Foo;
+import com.baeldung.flips.service.FlipService;
+import org.flips.annotation.FlipOnDateTime;
+import org.flips.annotation.FlipOnDaysOfWeek;
+import org.flips.annotation.FlipOnEnvironmentProperty;
+import org.flips.annotation.FlipOnProfiles;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.DayOfWeek;
+import java.util.List;
+
+@RestController
+public class FlipController {
+
+ private FlipService flipService;
+
+ @Autowired
+ public FlipController(FlipService flipService) {
+ this.flipService = flipService;
+ }
+
+ @RequestMapping(value = "/foos", method = RequestMethod.GET)
+ @FlipOnProfiles(activeProfiles = "dev")
+ public List getAllFoos() {
+ return flipService.getAllFoos();
+ }
+
+ @RequestMapping(value = "/foo/{id}", method = RequestMethod.GET)
+ @FlipOnDaysOfWeek(daysOfWeek = {
+ DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY,
+ DayOfWeek.FRIDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY
+ })
+ public Foo getFooByNewId(@PathVariable int id) {
+ return flipService.getFooById(id).orElse(new Foo("Not Found", -1));
+ }
+
+ @RequestMapping(value = "/foo/last", method = RequestMethod.GET)
+ @FlipOnDateTime(cutoffDateTimeProperty = "last.active.after")
+ public Foo getLastFoo() {
+ return flipService.getLastFoo();
+ }
+
+ @RequestMapping(value = "/foo/first", method = RequestMethod.GET)
+ @FlipOnDateTime(cutoffDateTimeProperty = "first.active.after")
+ public Foo getFirstFoo() {
+ return flipService.getLastFoo();
+ }
+
+ @RequestMapping(value = "/foos/{id}", method = RequestMethod.GET)
+ @FlipOnEnvironmentProperty(property = "feature.foo.by.id", expectedValue = "Y")
+ public Foo getFooById(@PathVariable int id) {
+ return flipService.getFooById(id).orElse(new Foo("Not Found", -1));
+ }
+
+ @RequestMapping(value = "/foo/new", method = RequestMethod.GET)
+ public Foo getNewThing() {
+ return flipService.getNewFoo();
+ }
+}
\ No newline at end of file
diff --git a/flips/src/main/java/com/baeldung/flips/model/Foo.java b/flips/src/main/java/com/baeldung/flips/model/Foo.java
new file mode 100644
index 0000000000..d98abb79a9
--- /dev/null
+++ b/flips/src/main/java/com/baeldung/flips/model/Foo.java
@@ -0,0 +1,11 @@
+package com.baeldung.flips.model;
+
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+
+@Data
+@RequiredArgsConstructor
+public class Foo {
+ private final String name;
+ private final int id;
+}
diff --git a/flips/src/main/java/com/baeldung/flips/service/FlipService.java b/flips/src/main/java/com/baeldung/flips/service/FlipService.java
new file mode 100644
index 0000000000..9f7fb325a5
--- /dev/null
+++ b/flips/src/main/java/com/baeldung/flips/service/FlipService.java
@@ -0,0 +1,50 @@
+package com.baeldung.flips.service;
+
+import com.baeldung.flips.model.Foo;
+import org.flips.annotation.FlipBean;
+import org.flips.annotation.FlipOnSpringExpression;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class FlipService {
+
+ private final List foos;
+
+ public FlipService() {
+ foos = new ArrayList<>();
+ foos.add(new Foo("Foo1", 1));
+ foos.add(new Foo("Foo2", 2));
+ foos.add(new Foo("Foo3", 3));
+ foos.add(new Foo("Foo4", 4));
+ foos.add(new Foo("Foo5", 5));
+ foos.add(new Foo("Foo6", 6));
+
+ }
+
+ public List getAllFoos() {
+ return foos;
+ }
+
+ public Optional getFooById(int id) {
+ return foos.stream().filter(foo -> (foo.getId() == id)).findFirst();
+ }
+
+ @FlipBean(with = NewFlipService.class)
+ @FlipOnSpringExpression(expression = "(2 + 2) == 4")
+ public Foo getNewFoo() {
+ return new Foo("New Foo!", 99);
+ }
+
+ public Foo getLastFoo() {
+ return foos.get(foos.size() - 1);
+ }
+
+ public Foo getFirstFoo() {
+ return foos.get(0);
+ }
+
+}
\ No newline at end of file
diff --git a/flips/src/main/java/com/baeldung/flips/service/NewFlipService.java b/flips/src/main/java/com/baeldung/flips/service/NewFlipService.java
new file mode 100644
index 0000000000..1dcda9b6ca
--- /dev/null
+++ b/flips/src/main/java/com/baeldung/flips/service/NewFlipService.java
@@ -0,0 +1,13 @@
+package com.baeldung.flips.service;
+
+import com.baeldung.flips.model.Foo;
+import org.springframework.stereotype.Service;
+
+@Service
+public class NewFlipService {
+
+ public Foo getNewFoo() {
+ return new Foo("Shiny New Foo!", 100);
+ }
+
+}
\ No newline at end of file
diff --git a/flips/src/main/resources/application.properties b/flips/src/main/resources/application.properties
new file mode 100644
index 0000000000..274896be15
--- /dev/null
+++ b/flips/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+feature.foo.by.id=Y
+feature.new.foo=Y
+last.active.after=2018-03-14T00:00:00Z
+first.active.after=2999-03-15T00:00:00Z
+logging.level.org.flips=info
\ No newline at end of file
diff --git a/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java b/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java
new file mode 100644
index 0000000000..1b8c78e2a4
--- /dev/null
+++ b/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java
@@ -0,0 +1,74 @@
+package com.baeldung.flips.controller;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(properties = {
+ "feature.foo.by.id=Y",
+ "feature.new.foo=Y",
+ "last.active.after=2018-03-14T00:00:00Z",
+ "first.active.after=2999-03-15T00:00:00Z",
+ "logging.level.org.flips=info"
+
+})
+@AutoConfigureMockMvc
+@ActiveProfiles("dev")
+public class FlipControllerTest {
+
+ @Autowired private MockMvc mvc;
+
+ @Test
+ public void givenValidDayOfWeek_APIAvailable() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/foo/1"))
+ .andExpect(MockMvcResultMatchers.status().is(200))
+ .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo1")))
+ .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(1)));
+ }
+
+ @Test
+ public void givenValidDate_APIAvailable() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/foo/last"))
+ .andExpect(MockMvcResultMatchers.status().is(200))
+ .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo6")))
+ .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(6)));
+ }
+
+ @Test
+ public void givenInvalidDate_APINotAvailable() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/foo/first"))
+ .andExpect(MockMvcResultMatchers.status().is(501));
+ }
+
+ @Test
+ public void givenCorrectProfile_APIAvailable() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/foos"))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andExpect(MockMvcResultMatchers.jsonPath("$", Matchers.hasSize(6)));
+ }
+
+ @Test
+ public void givenPropertySet_APIAvailable() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/foos/1"))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Foo1")))
+ .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(1)));
+ }
+
+ @Test
+ public void getValidExpression_FlipBean() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/foo/new"))
+ .andExpect(MockMvcResultMatchers.status().is(200))
+ .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo("Shiny New Foo!")))
+ .andExpect(MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(100)));
+ }
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java
index adb0fe0413..0e2a52e75c 100644
--- a/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java
@@ -14,6 +14,7 @@ import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.fasterxml.jackson.annotation.JsonProperty;
public class XMLSerializeDeserializeUnitTest {
@@ -48,6 +49,24 @@ public class XMLSerializeDeserializeUnitTest {
assertTrue(value.getX() == 1 && value.getY() == 2);
}
+ @Test
+ public void whenJavaGotFromXmlStrWithCapitalElem_thenCorrect() throws IOException {
+ XmlMapper xmlMapper = new XmlMapper();
+ SimpleBeanForCapitalizedFields value = xmlMapper.
+ readValue("12",
+ SimpleBeanForCapitalizedFields.class);
+ assertTrue(value.getX() == 1 && value.getY() == 2);
+ }
+
+ @Test
+ public void whenJavaSerializedToXmlFileWithCapitalizedField_thenCorrect() throws IOException {
+ XmlMapper xmlMapper = new XmlMapper();
+ xmlMapper.writeValue(new File("target/simple_bean_capitalized.xml"),
+ new SimpleBeanForCapitalizedFields());
+ File file = new File("target/simple_bean_capitalized.xml");
+ assertNotNull(file);
+ }
+
private static String inputStreamToString(InputStream is) throws IOException {
BufferedReader br;
StringBuilder sb = new StringBuilder();
@@ -83,3 +102,25 @@ class SimpleBean {
}
}
+
+class SimpleBeanForCapitalizedFields {
+ @JsonProperty("X")
+ private int x = 1;
+ private int y = 2;
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+}
\ No newline at end of file
diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/CookieReader.java b/javax-servlets/src/main/java/com/baeldung/servlets/CookieReader.java
new file mode 100644
index 0000000000..c2d875a69f
--- /dev/null
+++ b/javax-servlets/src/main/java/com/baeldung/servlets/CookieReader.java
@@ -0,0 +1,39 @@
+package com.baeldung.servlets;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+
+/**
+ * Created by adam.
+ *
+ * Class which simplifies reading cookies from request.
+ */
+public class CookieReader {
+
+ private HttpServletRequest request;
+
+ /**
+ * The constructor.
+ *
+ * @param request request from which cookies will be read
+ */
+ public CookieReader(HttpServletRequest request) {
+ this.request = request;
+ }
+
+ /**
+ * Reads cookie by key from request.
+ *
+ * @param key the key of a cookie
+ * @return returns cookie value (or null if cookie with given key does not exist)
+ */
+ public String readCookie(String key) {
+ return Arrays.stream(request.getCookies())
+ .filter(c -> key.equals(c.getName()))
+ .map(Cookie::getValue)
+ .findFirst()
+ .orElse(null);
+ }
+
+}
diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/LoginServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/LoginServlet.java
new file mode 100644
index 0000000000..deb0e05ec4
--- /dev/null
+++ b/javax-servlets/src/main/java/com/baeldung/servlets/LoginServlet.java
@@ -0,0 +1,48 @@
+package com.baeldung.servlets;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.*;
+import java.io.IOException;
+
+/**
+ * Created by adam.
+ */
+@WebServlet(name = "LoginServlet", urlPatterns = "/login")
+public class LoginServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ CookieReader cookieReader = new CookieReader(request);
+ String uiColor = cookieReader.readCookie("uiColor");
+ String userName = cookieReader.readCookie("userName");
+
+ request.setAttribute("uiColor", uiColor != null ? uiColor : "blue");
+
+ if (userName == null || userName.isEmpty()) {
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/login.jsp");
+ dispatcher.forward(request, response);
+ } else {
+ response.sendRedirect("/welcome");
+ }
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ HttpSession session = request.getSession();
+ session.setAttribute("sampleKey", "Sample Value");
+
+ String uiColor = request.getParameter("color");
+ String userName = request.getParameter("name");
+
+ Cookie uiColorCookie = new Cookie("uiColor", uiColor);
+ response.addCookie(uiColorCookie);
+
+ Cookie userNameCookie = new Cookie("userName", userName);
+ response.addCookie(userNameCookie);
+
+ response.sendRedirect("/welcome");
+ }
+
+}
diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/WelcomeServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/WelcomeServlet.java
new file mode 100644
index 0000000000..b35be2fc93
--- /dev/null
+++ b/javax-servlets/src/main/java/com/baeldung/servlets/WelcomeServlet.java
@@ -0,0 +1,45 @@
+package com.baeldung.servlets;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Created by adam.
+ */
+@WebServlet(name = "WelcomeServlet", urlPatterns = "/welcome")
+public class WelcomeServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ CookieReader cookieReader = new CookieReader(request);
+ String uiColor = cookieReader.readCookie("uiColor");
+ String userName = cookieReader.readCookie("userName");
+
+ if (userName == null || userName.isEmpty()) {
+ response.sendRedirect("/login");
+ } else {
+ request.setAttribute("uiColor", uiColor != null ? uiColor : "blue");
+ request.setAttribute("userName", userName);
+ request.setAttribute("sessionAttribute", request.getSession().getAttribute("sampleKey"));
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/welcome.jsp");
+ dispatcher.forward(request, response);
+ }
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ Cookie userNameCookieRemove = new Cookie("userName", "");
+ userNameCookieRemove.setMaxAge(0);
+ response.addCookie(userNameCookieRemove);
+
+ response.sendRedirect("/login");
+ }
+
+}
diff --git a/javax-servlets/src/main/webapp/WEB-INF/jsp/login.jsp b/javax-servlets/src/main/webapp/WEB-INF/jsp/login.jsp
new file mode 100644
index 0000000000..49babaadad
--- /dev/null
+++ b/javax-servlets/src/main/webapp/WEB-INF/jsp/login.jsp
@@ -0,0 +1,17 @@
+<%@ page contentType="text/html;charset=UTF-8"%>
+
+
+ Hello New User:
+
+
+
+
+
diff --git a/javax-servlets/src/main/webapp/WEB-INF/jsp/welcome.jsp b/javax-servlets/src/main/webapp/WEB-INF/jsp/welcome.jsp
new file mode 100644
index 0000000000..67cdb8926b
--- /dev/null
+++ b/javax-servlets/src/main/webapp/WEB-INF/jsp/welcome.jsp
@@ -0,0 +1,13 @@
+<%@ page contentType="text/html;charset=UTF-8"%>
+
+
+ Hello Known User:
+
+
+
+
+
diff --git a/libraries/src/main/java/com/baeldung/flips/TestFlipsBean.java b/libraries/src/main/java/com/baeldung/flips/TestFlipsBean.java
new file mode 100644
index 0000000000..e274e4ff0d
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/flips/TestFlipsBean.java
@@ -0,0 +1,4 @@
+package com.baeldung.flips;
+
+public class TestFlipsBean {
+}
diff --git a/pom.xml b/pom.xml
index 6118e81288..cf9de13ba4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,6 +64,7 @@
feign
+ flips
diff --git a/spring-mvc-forms-thymeleaf/README.md b/spring-mvc-forms-thymeleaf/README.md
new file mode 100644
index 0000000000..450b10433c
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/README.md
@@ -0,0 +1,3 @@
+### Relevant articles
+
+- [Session Attributes in Spring MVC](http://www.baeldung.com/spring-mvc-session-attributes)
diff --git a/spring-mvc-java/pom.xml b/spring-mvc-java/pom.xml
index 9d90ba2dbf..9b2981a747 100644
--- a/spring-mvc-java/pom.xml
+++ b/spring-mvc-java/pom.xml
@@ -1,5 +1,5 @@
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.baeldung
spring-mvc-java
@@ -7,38 +7,42 @@
spring-mvc-java
+ parent-boot-5
com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
+ 0.0.1-SNAPSHOT
+ ../parent-boot-5
-
+
- org.springframework
- spring-web
- ${org.springframework.version}
-
-
- commons-logging
- commons-logging
-
-
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
- org.springframework
- spring-webmvc
- ${org.springframework.version}
+ org.springframework.boot
+ spring-boot-starter-actuator
- org.springframework
- spring-websocket
- ${org.springframework.version}
+ org.springframework.boot
+ spring-boot-devtools
- org.springframework
- spring-messaging
- ${org.springframework.version}
+ org.springframework.boot
+ spring-boot-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
@@ -63,11 +67,6 @@
-
- org.springframework
- spring-aop
- ${org.springframework.version}
-
org.aspectj
aspectjrt
@@ -118,7 +117,6 @@
org.springframework
spring-test
- ${org.springframework.version}
test
@@ -294,8 +292,6 @@
- 4.3.4.RELEASE
- 4.2.0.RELEASE
2.1.5.RELEASE
2.9.4
@@ -317,7 +313,7 @@
4.4.5
4.5.2
- 2.9.0
+ 3.0.7
2.23
diff --git a/spring-mvc-java/src/main/java/com/baeldung/app/Application.java b/spring-mvc-java/src/main/java/com/baeldung/app/Application.java
new file mode 100644
index 0000000000..301caffca9
--- /dev/null
+++ b/spring-mvc-java/src/main/java/com/baeldung/app/Application.java
@@ -0,0 +1,17 @@
+package com.baeldung.app;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
+
+@EnableAutoConfiguration
+@ComponentScan(value = {"com.baeldung.web.controller"}, resourcePattern = "**/FileUploadController.class")
+@SpringBootApplication
+public class Application extends SpringBootServletInitializer {
+
+ public static void main(final String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
\ No newline at end of file
diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java
index 6fefd4e06d..79ba882205 100644
--- a/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java
+++ b/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java
@@ -1,11 +1,156 @@
package com.baeldung;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static java.time.Duration.ofSeconds;
+import static java.util.Arrays.asList;
+import static org.junit.jupiter.api.Assertions.*;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.BooleanSupplier;
+
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+/**
+ * Unit test that demonstrate the different assertions available within JUnit 4
+ */
public class AssertionUnitTest {
+ @Test
+ public void whenAssertingArraysEquality_thenEqual() {
+ char[] expected = {'J', 'u', 'p', 'i', 't', 'e', 'r'};
+ char[] actual = "Jupiter".toCharArray();
+
+ assertArrayEquals(expected, actual, "Arrays should be equal");
+ }
+
+ @Test
+ public void whenAssertingEquality_thenEqual() {
+ float square = 2 * 2;
+ float rectangle = 2 * 2;
+
+ assertEquals(square, rectangle);
+ }
+
+ @Test
+ public void whenAssertingEqualityWithDelta_thenEqual() {
+ float square = 2 * 2;
+ float rectangle = 3 * 2;
+ float delta = 2;
+
+ assertEquals(square, rectangle, delta);
+ }
+
+ @Test
+ public void whenAssertingConditions_thenVerified() {
+ assertTrue(5 > 4, "5 is greater the 4");
+ assertTrue(null == null, "null is equal to null");
+ }
+
+ @Test
+ public void whenAssertingNull_thenTrue() {
+ Object cat = null;
+
+ assertNull(cat, () -> "The cat should be null");
+ }
+
+ @Test
+ public void whenAssertingNotNull_thenTrue() {
+ Object dog = new Object();
+
+ assertNotNull(dog, () -> "The dog should not be null");
+ }
+
+ @Test
+ public void whenAssertingSameObject_thenSuccessfull() {
+ String language = "Java";
+ Optional optional = Optional.of(language);
+
+ assertSame(language, optional.get());
+ }
+
+ @Test
+ public void givenBooleanSupplier_whenAssertingCondition_thenVerified() {
+ BooleanSupplier condition = () -> 5 > 6;
+
+ assertFalse(condition, "5 is not greater then 6");
+ }
+
+ @Test
+ @Disabled
+ public void whenFailingATest_thenFailed() {
+ // Test not completed
+ fail("FAIL - test not completed");
+ }
+
+ @Test
+ public void givenMultipleAssertion_whenAssertingAll_thenOK() {
+ assertAll(
+ "heading",
+ () -> assertEquals(4, 2 * 2, "4 is 2 times 2"),
+ () -> assertEquals("java", "JAVA".toLowerCase()),
+ () -> assertEquals(null, null, "null is equal to null")
+ );
+ }
+
+ @Test
+ public void givenTwoLists_whenAssertingIterables_thenEquals() {
+ Iterable al = new ArrayList<>(asList("Java", "Junit", "Test"));
+ Iterable ll = new LinkedList<>(asList("Java", "Junit", "Test"));
+
+ assertIterableEquals(al, ll);
+ }
+
+ @Test
+ public void whenAssertingTimeout_thenNotExceeded() {
+ assertTimeout(
+ ofSeconds(2),
+ () -> {
+ // code that requires less then 2 minutes to execute
+ Thread.sleep(1000);
+ }
+ );
+ }
+
+ @Test
+ public void whenAssertingTimeoutPreemptively_thenNotExceeded() {
+ assertTimeoutPreemptively(
+ ofSeconds(2),
+ () -> {
+ // code that requires less then 2 minutes to execute
+ Thread.sleep(1000);
+ }
+ );
+ }
+
+ @Test
+ public void whenAssertingEquality_thenNotEqual() {
+ Integer value = 5; // result of an algorithm
+
+ assertNotEquals(0, value, "The result cannot be 0");
+ }
+
+ @Test
+ public void whenAssertingEqualityListOfStrings_thenEqual() {
+ List expected = asList("Java", "\\d+", "JUnit");
+ List actual = asList("Java", "11", "JUnit");
+
+ assertLinesMatch(expected, actual);
+ }
+
+ @Test
+ void whenAssertingException_thenThrown() {
+ Throwable exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> {
+ throw new IllegalArgumentException("Exception message");
+ }
+ );
+ assertEquals("Exception message", exception.getMessage());
+ }
+
@Test
public void testConvertToDoubleThrowException() {
String age = "eighteen";
diff --git a/testing-modules/mockito/src/main/java/org/baeldung/hamcrest/City.java b/testing-modules/mockito/src/main/java/org/baeldung/hamcrest/City.java
new file mode 100644
index 0000000000..d6369189c1
--- /dev/null
+++ b/testing-modules/mockito/src/main/java/org/baeldung/hamcrest/City.java
@@ -0,0 +1,41 @@
+package org.baeldung.hamcrest;
+
+public class City extends Location {
+ String name;
+ String state;
+
+ public City(String name, String state) {
+ this.name = name;
+ this.state = state;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ @Override
+ public String toString() {
+ if (this.name == null && this.state == null) return null;
+ StringBuilder sb = new StringBuilder();
+ sb.append("[");
+ sb.append("Name: ");
+ sb.append(this.name);
+ sb.append(", ");
+ sb.append("State: ");
+ sb.append(this.state);
+ sb.append("]");
+ return sb.toString();
+ }
+}
diff --git a/testing-modules/mockito/src/main/java/org/baeldung/hamcrest/Location.java b/testing-modules/mockito/src/main/java/org/baeldung/hamcrest/Location.java
new file mode 100644
index 0000000000..52561d07dc
--- /dev/null
+++ b/testing-modules/mockito/src/main/java/org/baeldung/hamcrest/Location.java
@@ -0,0 +1,4 @@
+package org.baeldung.hamcrest;
+
+public class Location {
+}
diff --git a/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestBeansUnitTest.java b/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestBeansUnitTest.java
new file mode 100644
index 0000000000..e7eb9bda1b
--- /dev/null
+++ b/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestBeansUnitTest.java
@@ -0,0 +1,91 @@
+package org.baeldung.hamcrest;
+
+import org.junit.Test;
+
+import java.beans.PropertyDescriptor;
+import java.util.Arrays;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasProperty;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.equalToIgnoringCase;
+import static org.hamcrest.Matchers.samePropertyValuesAs;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.beans.PropertyUtil.getPropertyDescriptor;
+import static org.hamcrest.beans.PropertyUtil.propertyDescriptorsFor;
+
+public class HamcrestBeansUnitTest {
+
+ @Test
+ public void givenACity_whenHasProperty_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city, hasProperty("name"));
+ }
+
+ @Test
+ public void givenACity_whenNotHasProperty_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city, not(hasProperty("country")));
+ }
+
+ @Test
+ public void givenACity_whenHasPropertyWithValueEqualTo_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city, hasProperty("name", equalTo("San Francisco")));
+ }
+
+ @Test
+ public void givenACity_whenHasPropertyWithValueEqualToIgnoringCase_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city, hasProperty("state", equalToIgnoringCase("ca")));
+ }
+
+ @Test
+ public void givenACity_whenSamePropertyValuesAs_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+ City city2 = new City("San Francisco", "CA");
+
+ assertThat(city, samePropertyValuesAs(city2));
+ }
+
+ @Test
+ public void givenACity_whenNotSamePropertyValuesAs_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+ City city2 = new City("Los Angeles", "CA");
+
+ assertThat(city, not(samePropertyValuesAs(city2)));
+ }
+
+ @Test
+ public void givenACity_whenGetPropertyDescriptor_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+ PropertyDescriptor descriptor = getPropertyDescriptor("state", city);
+
+ assertThat(descriptor
+ .getReadMethod()
+ .getName(), is(equalTo("getState")));
+ }
+
+ @Test
+ public void givenACity_whenGetPropertyDescriptorsFor_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+ PropertyDescriptor[] descriptors = propertyDescriptorsFor(city, Object.class);
+ List getters = Arrays
+ .stream(descriptors)
+ .map(x -> x
+ .getReadMethod()
+ .getName())
+ .collect(toList());
+
+ assertThat(getters, containsInAnyOrder("getName", "getState"));
+ }
+
+}
\ No newline at end of file
diff --git a/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestObjectUnitTest.java b/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestObjectUnitTest.java
new file mode 100644
index 0000000000..8d30ff297b
--- /dev/null
+++ b/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestObjectUnitTest.java
@@ -0,0 +1,57 @@
+package org.baeldung.hamcrest;
+
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasToString;
+import static org.hamcrest.Matchers.equalToIgnoringCase;
+import static org.hamcrest.Matchers.emptyOrNullString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.typeCompatibleWith;
+import static org.hamcrest.Matchers.not;
+
+public class HamcrestObjectUnitTest {
+
+ @Test
+ public void givenACity_whenHasToString_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city, hasToString("[Name: San Francisco, State: CA]"));
+ }
+
+ @Test
+ public void givenACity_whenHasToStringEqualToIgnoringCase_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city, hasToString(equalToIgnoringCase("[NAME: SAN FRANCISCO, STATE: CA]")));
+ }
+
+ @Test
+ public void givenACity_whenHasToStringEmptyOrNullString_thenCorrect() {
+ City city = new City(null, null);
+
+ assertThat(city, hasToString(emptyOrNullString()));
+ }
+
+ @Test
+ public void givenACity_whenTypeCompatibleWithLocation_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city.getClass(), is(typeCompatibleWith(Location.class)));
+ }
+
+ @Test
+ public void givenACity_whenTypeNotCompatibleWithString_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city.getClass(), is(not(typeCompatibleWith(String.class))));
+ }
+
+ @Test
+ public void givenACity_whenTypeCompatibleWithObject_thenCorrect() {
+ City city = new City("San Francisco", "CA");
+
+ assertThat(city.getClass(), is(typeCompatibleWith(Object.class)));
+ }
+
+}
diff --git a/testing-modules/testing/src/test/java/com/baeldung/junit/AssertionsUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/junit/AssertionsUnitTest.java
new file mode 100644
index 0000000000..b0209b01aa
--- /dev/null
+++ b/testing-modules/testing/src/test/java/com/baeldung/junit/AssertionsUnitTest.java
@@ -0,0 +1,101 @@
+package com.baeldung.junit;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.hamcrest.core.IsCollectionContaining.hasItems;
+import static org.junit.Assert.*;
+
+/**
+ * Unit test that demonstrate the different assertions available within JUnit 4
+ */
+public class AssertionsUnitTest {
+
+ @Test
+ public void whenAssertingEquality_thenEqual() {
+ String expected = "Baeldung";
+ String actual = "Baeldung";
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void whenAssertingEqualityWithMessage_thenEqual() {
+ String expected = "Baeldung";
+ String actual = "Baeldung";
+
+ assertEquals("failure - strings are not equal", expected, actual);
+ }
+
+ @Test
+ public void whenAssertingArraysEquality_thenEqual() {
+ char[] expected = { 'J', 'u', 'n', 'i', 't' };
+ char[] actual = "Junit".toCharArray();
+
+ assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void givenNullArrays_whenAssertingArraysEquality_thenEqual() {
+ int[] expected = null;
+ int[] actual = null;
+
+ assertArrayEquals(expected, actual);
+ }
+
+ @Test
+ public void whenAssertingNull_thenTrue() {
+ Object car = null;
+
+ assertNull("The car should be null", car);
+ }
+
+ @Test
+ public void whenAssertingNotNull_thenTrue() {
+ Object car = new Object();
+
+ assertNotNull("The car should not be null", car);
+ }
+
+ @Test
+ public void whenAssertingNotSameObject_thenDifferent() {
+ Object cat = new Object();
+ Object dog = new Object();
+
+ assertNotSame(cat, dog);
+ }
+
+ @Test
+ public void whenAssertingSameObject_thenSame() {
+ Object cat = new Object();
+
+ assertSame(cat, cat);
+ }
+
+ @Test
+ public void whenAssertingConditions_thenVerified() {
+ assertTrue("5 is greater then 4", 5 > 4);
+ assertFalse("5 is not greater then 6", 5 > 6);
+ }
+
+ @Test
+ public void when_thenNotFailed() {
+ try {
+ methodThatShouldThrowException();
+ fail("Exception not thrown");
+ } catch (UnsupportedOperationException e) {
+ assertEquals("Operation Not Supported", e.getMessage());
+ }
+ }
+
+ private void methodThatShouldThrowException() {
+ throw new UnsupportedOperationException("Operation Not Supported");
+ }
+
+ @Test
+ public void testAssertThatHasItems() {
+ assertThat(Arrays.asList("Java", "Kotlin", "Scala"), hasItems("Java", "Kotlin"));
+ }
+
+}