package com.codepoetics.octarine.functional.lenses; import com.codepoetics.octarine.functional.morphisms.Bijection; import org.junit.Test; import org.pcollections.HashTreePMap; import org.pcollections.PMap; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.function.Function; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; public class LensesTest { private static final Lens<PMap<String, String>, String> aIsFor = Lens.intoPMap("a"); private static final Bijection<String, Character[]> stringToChars = Bijection.of( (String s) -> { Character[] characters = new Character[s.length()]; char[] chars = s.toCharArray(); for (int i = 0; i < s.length(); i++) { characters[i] = chars[i]; } return characters; }, (Character[] cs) -> { StringBuilder sb = new StringBuilder(); Arrays.stream(cs).forEach(sb::append); return sb.toString(); } ); private static final Lens<String, Character> thirdChar = stringToChars.overSource(Lens.<Character>intoArray(2)); private static final Map<String, String> map = new HashMap<>(); static { map.put("a", "apple"); } private static final PMap<String, String> pmap = HashTreePMap.from(map); @Test public void lenses_can_be_composed_out_of_functions() { assertThat(aIsFor.get(pmap), equalTo("apple")); assertThat(aIsFor.set(pmap, "artichoke").get("a"), equalTo("artichoke")); } @Test public void lenses_compose_with_bijections() { assertThat(thirdChar.get("Hello World"), equalTo('l')); assertThat(thirdChar.set("Hello World", 'f'), equalTo("Heflo World")); } @Test public void lenses_can_be_joined_together() { Lens<PMap<String, String>, Character> thirdCharOfA = aIsFor.join(thirdChar); assertThat(thirdCharOfA.get(pmap), equalTo('p')); assertThat(thirdCharOfA.set(pmap, 's').get("a"), equalTo("apsle")); } @Test public void can_behave_as_an_optional_lens_converting_null_to_empty() { String[] strings = new String[] { "a string", null, "another string" }; OptionalLens<String[], String> firstItem = Lens.<String>intoArray(0).asOptional(); OptionalLens<String[], String> secondItem = Lens.<String>intoArray(1).asOptional(); assertThat(firstItem.get(strings), equalTo(Optional.of("a string"))); assertThat(secondItem.get(strings), equalTo(Optional.empty())); } @Test public void can_create_an_injector() { String[] strings = new String[] { "a string", null, "another string" }; Lens<String[], String> secondItem = Lens.<String>intoArray(1); Function<String[], String[]> injector = secondItem.inject("the missing string"); assertThat(injector.apply(strings), equalTo(new String[]{"a string", "the missing string", "another string"})); } @Test public void can_create_an_inflector() { String[] strings = new String[] { "cow", "duck" }; Lens<String[], String> secondItem = Lens.<String>intoArray(1); Function<String[], String[]> secondItemPluraliser = secondItem.inflect(s -> s + "s"); assertThat(secondItemPluraliser.apply(strings), equalTo(new String[]{"cow", "ducks"})); } }