From babd9da4929ca66e3074c7fe04adabeb56817ab7 Mon Sep 17 00:00:00 2001 From: Egima profile Date: Wed, 28 Dec 2016 10:33:38 +0300 Subject: [PATCH] Javaslang project (#927) * made changes to java reflection * removed redundant method makeSound in Animal abstract class * added project for play-framework article * added project for regex * changed regex project from own model to core-java * added project for routing in play * made changes to regex project * refactored code for REST API with Play project * refactored student store indexing to zero base * added unit tests, removed bad names * added NIO Selector project under core-java module * requested changes made * added project for nio2 * standardized exception based tests * fixed exception based tests * removed redundant files * added network interface project * used UUID other than timestamps * fixed network interface tests * removed filetest change * made changes to NIO2 FileTest names * added project for asyncronous channel apis * added project for NIO2 advanced filesystems APIS * merge conflicts * merged changes to asyncfiletest with future get API * removed while loops from async client and server * added project for java8 optional * fixed merge conflicts in spring-core * fixed optional * fixed optional * fixed asyncechotest * shifted optional to own package * made additional tests to demo filter API * added code for Map * added javaslang project * javaslang project * added pattern matcher code --- javaslang/pom.xml | 41 +++ .../java/com/baeldung/javaslang/Person.java | 38 ++ .../baeldung/javaslang/PersonValidator.java | 22 ++ .../com/baeldung/javaslang/JavaSlangTest.java | 338 ++++++++++++++++++ .../javaslang/PatternMatchingTest.java | 114 ++++++ pom.xml | 1 + 6 files changed, 554 insertions(+) create mode 100644 javaslang/pom.xml create mode 100644 javaslang/src/main/java/com/baeldung/javaslang/Person.java create mode 100644 javaslang/src/main/java/com/baeldung/javaslang/PersonValidator.java create mode 100644 javaslang/src/test/java/com/baeldung/javaslang/JavaSlangTest.java create mode 100644 javaslang/src/test/java/com/baeldung/javaslang/PatternMatchingTest.java diff --git a/javaslang/pom.xml b/javaslang/pom.xml new file mode 100644 index 0000000000..fecbeeea4f --- /dev/null +++ b/javaslang/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + com.baeldung + Javaslang + 1.0 + Javaslang + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + + + + + + + junit + junit + 4.12 + test + + + org.hamcrest + hamcrest-all + 1.3 + + + io.javaslang + javaslang + 2.1.0-alpha + + + + + diff --git a/javaslang/src/main/java/com/baeldung/javaslang/Person.java b/javaslang/src/main/java/com/baeldung/javaslang/Person.java new file mode 100644 index 0000000000..38a6603f98 --- /dev/null +++ b/javaslang/src/main/java/com/baeldung/javaslang/Person.java @@ -0,0 +1,38 @@ +package com.baeldung.javaslang; + +public class Person { + private String name; + private int age; + + public Person(String name, int age) { + super(); + this.name = name; + this.age = age; + } + + public Person() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "Person [name=" + name + ", age=" + age + "]"; + } + +} diff --git a/javaslang/src/main/java/com/baeldung/javaslang/PersonValidator.java b/javaslang/src/main/java/com/baeldung/javaslang/PersonValidator.java new file mode 100644 index 0000000000..fb30d6072c --- /dev/null +++ b/javaslang/src/main/java/com/baeldung/javaslang/PersonValidator.java @@ -0,0 +1,22 @@ +package com.baeldung.javaslang; + +import javaslang.collection.List; +import javaslang.control.Validation; + +class PersonValidator { + String NAME_ERR = "Invalid characters in name: "; + String AGE_ERR = "Age must be at least 0"; + + public Validation, Person> validatePerson(String name, int age) { + return Validation.combine(validateName(name), validateAge(age)).ap(Person::new); + } + + private Validation validateName(String name) { + String invalidChars = name.replaceAll("[a-zA-Z ]", ""); + return invalidChars.isEmpty() ? Validation.valid(name) : Validation.invalid(NAME_ERR + invalidChars); + } + + private Validation validateAge(int age) { + return age < 0 ? Validation.invalid(AGE_ERR) : Validation.valid(age); + } +} diff --git a/javaslang/src/test/java/com/baeldung/javaslang/JavaSlangTest.java b/javaslang/src/test/java/com/baeldung/javaslang/JavaSlangTest.java new file mode 100644 index 0000000000..ecba894723 --- /dev/null +++ b/javaslang/src/test/java/com/baeldung/javaslang/JavaSlangTest.java @@ -0,0 +1,338 @@ +package com.baeldung.javaslang; + +import static javaslang.API.$; +import static javaslang.API.Case; +import static javaslang.API.Match; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.IntStream; + +import org.junit.Test; + +import javaslang.Function0; +import javaslang.Function1; +import javaslang.Function2; +import javaslang.Function5; +import javaslang.Lazy; +import javaslang.Tuple; +import javaslang.Tuple2; +import javaslang.Tuple3; +import javaslang.collection.List; +import javaslang.control.Option; +import javaslang.control.Try; +import javaslang.control.Validation; + +public class JavaSlangTest { + @Test + public void givenList_whenSorts_thenCorrect() { + List sortedList = List.of(3, 2, 1).sorted(); + } + + /* + * Tuples + */ + // creating and element access + @Test + public void whenCreatesTuple_thenCorrect1() { + Tuple2 java8 = Tuple.of("Java", 8); + String element1 = java8._1; + int element2 = java8._2(); + + assertEquals("Java", element1); + assertEquals(8, element2); + } + + @Test + public void whenCreatesTuple_thenCorrect2() { + Tuple3 java8 = Tuple.of("Java", 8, 1.8); + String element1 = java8._1; + int element2 = java8._2(); + double element3 = java8._3(); + + assertEquals("Java", element1); + assertEquals(8, element2); + assertEquals(1.8, element3, 0.1); + } + + // mapping--component-wise(using Function interface) + @Test + public void givenTuple_whenMapsComponentWise_thenCorrect() { + Tuple2 java8 = Tuple.of("Java", 8); + Tuple2 mapOfJava8 = java8.map(s -> s + "slang", i -> i / 2); + int num = mapOfJava8._2(); + assertEquals("Javaslang", mapOfJava8._1); + + assertEquals(4, num); + + } + + // mapping--with one mapper(using BiFunction interface) + @Test + public void givenTuple_whenMapsWithOneMapper_thenCorrect() { + Tuple2 java8 = Tuple.of("Java", 8); + Tuple2 mapOfJava8 = java8.map((s, i) -> Tuple.of(s + "slang", i / 2)); + int num = mapOfJava8._2(); + assertEquals("Javaslang", mapOfJava8._1); + + assertEquals(4, num); + } + + // transforming a tuple + @Test + public void givenTuple_whenTransforms_thenCorrect() { + Tuple2 java8 = Tuple.of("Java", 8); + String transformed = java8.apply((s, i) -> s + "slang " + i / 2); + assertEquals("Javaslang 4", transformed); + } + + /* + * Functions + */ + @Test + public void givenJava8Function_whenWorks_thenCorrect() { + Function square = (num) -> num * num; + int result = square.apply(2); + assertEquals(4, result); + } + + @Test + public void givenJava8BiFunction_whenWorks_thenCorrect() { + BiFunction sum = (num1, num2) -> num1 + num2; + int result = sum.apply(5, 7); + assertEquals(12, result); + } + + @Test + public void givenJavaslangFunction_whenWorks_thenCorrect() { + Function1 square = (num) -> num * num; + Integer result = square.apply(2); + assertEquals(Integer.valueOf(4), result); + } + + @Test + public void givenJavaslangBiFunction_whenWorks_thenCorrect() { + Function2 sum = (num1, num2) -> num1 + num2; + Integer result = sum.apply(5, 7); + assertEquals(Integer.valueOf(12), result); + } + + @Test + public void whenCreatesFunction_thenCorrect0() { + Function0 getClazzName = () -> this.getClass().getName(); + String clazzName = getClazzName.apply(); + assertEquals("com.baeldung.javaslang.JavaSlangTest", clazzName); + } + + @Test + public void whenCreatesFunction_thenCorrect2() { + Function2 sum = (a, b) -> a + b; + int summed = sum.apply(5, 6); + assertEquals(11, summed); + } + + @Test + public void whenCreatesFunction_thenCorrect5() { + Function5 concat = (a, b, c, d, e) -> a + b + c + d + e; + String finalString = concat.apply("Hello ", "world", "! ", "Learn ", "Javaslang"); + assertEquals("Hello world! Learn Javaslang", finalString); + } + + @Test + public void whenCreatesFunctionFromMethodRef_thenCorrect() { + Function2 sum = Function2.of(this::sum); + int summed = sum.apply(5, 6); + assertEquals(11, summed); + } + + public int sum(int a, int b) { + return a + b; + } + + + /* + * Values + */ + // option + @Test + public void givenValue_whenNullCheckNeeded_thenCorrect() { + Object possibleNullObj = null; + if (possibleNullObj == null) + possibleNullObj = "someDefaultValue"; + assertNotNull(possibleNullObj); + } + + @Test(expected = NullPointerException.class) + public void givenValue_whenNullCheckNeeded_thenCorrect2() { + Object possibleNullObj = null; + assertEquals("somevalue", possibleNullObj.toString()); + } + + @Test + public void givenValue_whenCreatesOption_thenCorrect() { + Option noneOption = Option.of(null); + Option someOption = Option.of("val"); + assertEquals("None", noneOption.toString()); + assertEquals("Some(val)", someOption.toString()); + } + + @Test + public void givenNull_whenCreatesOption_thenCorrect() { + String name = null; + Option nameOption = Option.of(name); + assertEquals("baeldung", nameOption.getOrElse("baeldung")); + } + + @Test + public void givenNonNull_whenCreatesOption_thenCorrect() { + String name = "baeldung"; + Option nameOption = Option.of(name); + assertEquals("baeldung", nameOption.getOrElse("notbaeldung")); + } + + // try + @Test(expected = ArithmeticException.class) + public void givenBadCode_whenThrowsException_thenCorrect() { + int i = 1 / 0; + } + + @Test + public void givenBadCode_whenTryHandles_thenCorrect() { + Try result = Try.of(() -> 1 / 0); + assertTrue(result.isFailure()); + } + + @Test + public void givenBadCode_whenTryHandles_thenCorrect2() { + Try result = Try.of(() -> 1 / 0); + int errorSentinel = result.getOrElse(-1); + assertEquals(-1, errorSentinel); + } + +// @Test(expected = ArithmeticException.class) +// public void givenBadCode_whenTryHandles_thenCorrect3() { +// Try result = Try.of(() -> 1 / 0); +// result.getOrElseThrow(ArithmeticException::new); +// } + + // lazy + @Test + public void givenFunction_whenEvaluatesWithLazy_thenCorrect() { + Lazy lazy = Lazy.of(Math::random); + assertFalse(lazy.isEvaluated()); + + double val1 = lazy.get(); + assertTrue(lazy.isEvaluated()); + + double val2 = lazy.get(); + assertEquals(val1, val2, 0.1); + } + + // validation + @Test + public void whenValidationWorks_thenCorrect() { + PersonValidator personValidator = new PersonValidator(); + Validation, Person> valid = personValidator.validatePerson("John Doe", 30); + Validation, Person> invalid = personValidator.validatePerson("John? Doe!4", -1); + + assertEquals("Valid(Person [name=John Doe, age=30])", valid.toString()); + assertEquals("Invalid(List(Invalid characters in name: ?!4, Age must be at least 0))", invalid.toString()); + } + + /* + * collections + */ + // list + @Test(expected = UnsupportedOperationException.class) + public void whenImmutableCollectionThrows_thenCorrect() { + java.util.List wordList = Arrays.asList("abracadabra"); + java.util.List list = Collections.unmodifiableList(wordList); + list.add("boom"); + } + + @Test + public void whenSumsJava8List_thenCorrect() { + // Arrays.asList(1, 2, 3).stream().reduce((i, j) -> i + j); + int sum = IntStream.of(1, 2, 3).sum(); + assertEquals(6, sum); + } + + @Test + public void whenCreatesJavaslangList_thenCorrect() { + List intList = List.of(1, 2, 3); + assertEquals(3, intList.length()); + assertEquals(new Integer(1), intList.get(0)); + assertEquals(new Integer(2), intList.get(1)); + assertEquals(new Integer(3), intList.get(2)); + } + + @Test + public void whenSumsJavaslangList_thenCorrect() { + int sum = List.of(1, 2, 3).sum().intValue(); + assertEquals(6, sum); + } + + /* + * pattern matching + */ + @Test + public void whenIfWorksAsMatcher_thenCorrect() { + int input = 3; + String output; + if (input == 0) { + output = "zero"; + } + if (input == 1) { + output = "one"; + } + if (input == 2) { + output = "two"; + } + if (input == 3) { + output = "three"; + } else { + output = "unknown"; + } + assertEquals("three", output); + } + + @Test + public void whenSwitchWorksAsMatcher_thenCorrect() { + int input = 2; + String output; + switch (input) { + case 0: + output = "zero"; + break; + case 1: + output = "one"; + break; + case 2: + output = "two"; + break; + case 3: + output = "three"; + break; + default: + output = "unknown"; + break; + } + assertEquals("two", output); + } + + @Test + public void whenMatchworks_thenCorrect() { + int input = 2; + String output = Match(input).of(Case($(1), "one"), Case($(2), "two"), Case($(3), "three"), Case($(), "?")); + assertEquals("two", output); + } + + + +} diff --git a/javaslang/src/test/java/com/baeldung/javaslang/PatternMatchingTest.java b/javaslang/src/test/java/com/baeldung/javaslang/PatternMatchingTest.java new file mode 100644 index 0000000000..7ae7683a58 --- /dev/null +++ b/javaslang/src/test/java/com/baeldung/javaslang/PatternMatchingTest.java @@ -0,0 +1,114 @@ +package com.baeldung.javaslang; + +import static javaslang.API.$; +import static javaslang.API.Case; +import static javaslang.API.Match; +import static javaslang.API.run; +import static javaslang.Predicates.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Optional; + +import org.junit.Test; + +import javaslang.MatchError; +import javaslang.control.Option; + +public class PatternMatchingTest { + @Test + public void whenMatchesDefault_thenCorrect() { + int input = 5; + String output = Match(input).of(Case($(1), "one"), Case($(2), "two"), Case($(3), "three"), Case($(), "unknown")); + + assertEquals("unknown", output); + } + + @Test(expected = MatchError.class) + public void givenNoMatchAndNoDefault_whenThrows_thenCorrect() { + int input = 5; + Match(input).of(Case($(1), "one"), Case($(2), "two")); + } + + @Test + public void whenMatchWorksWithOption_thenCorrect() { + int i = 10; + Option s = Match(i).option(Case($(0), "zero")); + assertTrue(s.isEmpty()); + assertEquals("None", s.toString()); + } + + @Test + public void whenMatchWorksWithPredicate_thenCorrect() { + int i = 3; + String s = Match(i).of(Case(is(1), "one"), Case(is(2), "two"), Case(is(3), "three"), Case($(), "?")); + assertEquals("three", s); + } + + @Test + public void givenInput_whenMatchesClass_thenCorrect() { + Object obj = 5; + String s = Match(obj).of(Case(instanceOf(String.class), "string matched"), Case($(), "not string")); + assertEquals("not string", s); + } + + @Test + public void givenInput_whenMatchesNull_thenCorrect() { + Object obj = 5; + String s = Match(obj).of(Case(isNull(), "no value"), Case(isNotNull(), "value found")); + assertEquals("value found", s); + } + + @Test + public void givenInput_whenContainsWorks_thenCorrect() { + int i = 5; + String s = Match(i).of(Case(isIn(2, 4, 6, 8), "Even Single Digit"), Case(isIn(1, 3, 5, 7, 9), "Odd Single Digit"), Case($(), "Out of range")); + assertEquals("Odd Single Digit", s); + } + + @Test + public void givenInput_whenMatchAllWorks_thenCorrect() { + Integer i = null; + String s = Match(i).of(Case(allOf(isNotNull(), isIn(1, 2, 3, null)), "Number found"), Case($(), "Not found")); + assertEquals("Not found", s); + } + + @Test + public void givenInput_whenMatchesAnyOfWorks_thenCorrect() { + Integer year = 1990; + String s = Match(year).of(Case(anyOf(isIn(1990, 1991, 1992), is(1986)), "Age match"), Case($(), "No age match")); + assertEquals("Age match", s); + } + + @Test + public void givenInput_whenMatchesNoneOfWorks_thenCorrect() { + Integer year = 1990; + String s = Match(year).of(Case(noneOf(isIn(1990, 1991, 1992), is(1986)), "Age match"), Case($(), "No age match")); + assertEquals("No age match", s); + } + + @Test + public void whenMatchWorksWithPredicate_thenCorrect2() { + int i = 5; + String s = Match(i).of(Case(isIn(2, 4, 6, 8), "Even Single Digit"), Case(isIn(1, 3, 5, 7, 9), "Odd Single Digit"), Case($(), "Out of range")); + assertEquals("Odd Single Digit", s); + } + + @Test + public void whenMatchCreatesSideEffects_thenCorrect() { + int i = 4; + Match(i).of(Case(isIn(2, 4, 6, 8), o -> run(this::displayEven)), Case(isIn(1, 3, 5, 7, 9), o -> run(this::displayOdd)), Case($(), o -> run(() -> { + throw new IllegalArgumentException(String.valueOf(i)); + }))); + } + + + + public void displayEven() { + System.out.println("Input is even"); + } + + public void displayOdd() { + System.out.println("Input is odd"); + } +} diff --git a/pom.xml b/pom.xml index a61bd6ccd4..36b83290c3 100644 --- a/pom.xml +++ b/pom.xml @@ -172,6 +172,7 @@ xml xmlunit2 xstream + javaslang