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")); + } + +}