Package org.adoptopenjdk.lambda.tutorial

Source Code of org.adoptopenjdk.lambda.tutorial.Exercise_1_Test

package org.adoptopenjdk.lambda.tutorial;

/*
* #%L
* lambda-tutorial
* %%
* Copyright (C) 2013 Adopt OpenJDK
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program.  If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/

import org.adoptopenjdk.lambda.tutorial.exercise1.Color;
import org.adoptopenjdk.lambda.tutorial.exercise1.Shape;
import org.adoptopenjdk.lambda.tutorial.exercise1.Shapes;
import org.adoptopenjdk.lambda.tutorial.util.FeatureMatchers;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

import static org.adoptopenjdk.lambda.tutorial.exercise1.Color.BLACK;
import static org.adoptopenjdk.lambda.tutorial.exercise1.Color.BLUE;
import static org.adoptopenjdk.lambda.tutorial.exercise1.Color.GREEN;
import static org.adoptopenjdk.lambda.tutorial.exercise1.Color.RED;
import static org.adoptopenjdk.lambda.tutorial.exercise1.Color.YELLOW;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.hasSize;

/**
* Exercise 1 - Internal vs External iteration.
* <p>
* As described in Brian Goetz's State of the Lambda - Libraries Edition[0], Java's collection classes provide a way for
* clients to enumerate the members of a collection. Currently, this is iteration is "External" - that is, the
* collection can be iterated in sequence, by the client code.
* </p>
* <p>
* This refers to the trusty "for loop":
* TODO Bug in the Javdoc processor? It claims the code annotation construct is invalid
* <pre>
* {@code
*    for (Shape s: shapes) {
*       s.setColor(RED)
*    }
* }
* </pre>
* </p>
* <p>
* JDK 8, with lambdas and an updated Collections library, will allow "Internal" iteration. In this case, the collection
* receives some code, and decides how to apply that to its elements. This has several benefits, including:
*  - allowing the collection to decide how to handle executing given code, including opening the door to parallelism and laziness
*  - leads to a style where operations can be pipelined, into a more fluent, readable style.
* </p>
* <p>
* Internal iteration, using lambda expression syntax, turns the above for loop into:
* <pre>
* {@code
* shapes.forEach(s -> s.setColor(RED))
* }
* </pre>
* Where <code>s -> s.setColor(RED)</code> is a lambda expression, which is passed into forEach, and invoked inside forEach. Lambda
* expressions have a type, called a "Functional Interface". In this case the lambda is of type Consumer. Consumer declares
* a single method, <code>void accept(T t)</code>. This is all hidden by the Java compiler, and unless you extract the lambda
* to a variable, or write a method which accepts a lambda, you don't really need to know about it.
* </p>
* <p>
* The tests below can be made to pass using for loops. Try to make them pass without using a for loop.
* </p>
* [0] http://cr.openjdk.java.net/~briangoetz/lambda/sotc3.html
*
* @see java.lang.Iterable#forEach
* @see Shape
* @see Shapes
* @see Color
*
* @author Graham Allan grundlefleck at gmail dot com
*/
@SuppressWarnings("unchecked")
public class Exercise_1_Test {

    /**
     * Use forEach to change the color of every shape to RED.
     *
     * Change the 'method under test' to make the test pass.
     *
     * @see Shapes#colorAll(java.util.List, Color)
     *
     * @see Iterable#forEach
     * @see Shape#setColor(Color)
     */
    @Test
    public void changeColorOfAllShapes() {
        List<Shape> myShapes = Arrays.asList(new Shape(BLUE), new Shape(BLACK), new Shape(YELLOW));

        // method under test
        Shapes.colorAll(myShapes, RED);

        assertThat(myShapes, hasSize(3));
        assertThat(myShapes, everyItem(hasColor(RED)));
    }

    /**
     * Use forEach, with the given StringBuilder, to assemble a String which represents every Shape in the given list.
     *
     * Change the 'method under test' to make the test pass.
     *
     * The String should be a concatenation of each Shape's toString.
     *
     * @see Shapes#makeStringOfAllColors(java.util.List, StringBuilder)
     *
     * @see Shape#toString()
     * @see StringBuilder#append(String)
     * @see Iterable#forEach
     */
    @Test
    public void buildStringRepresentingAllShapes() {
        List<Shape> allMyShapes = Arrays.asList(new Shape(RED), new Shape(BLACK), new Shape(YELLOW));
        StringBuilder builder = new StringBuilder();

        // method under test
        Shapes.makeStringOfAllColors(allMyShapes, builder);

        assertThat(builder.toString(), equalTo("[a RED shape][a BLACK shape][a YELLOW shape]"));
    }

    /**
     * Use forEach to change the color, and build a string showing the old colors of each shape.
     *
     * Try to perform both actions using a single call to forEach.
     *
     * @see Shapes#changeColorAndMakeStringOfOldColors
     *
     * @see Shape#getColor()
     * @see Color#name()
     * @see StringBuilder#append(String)
     */
    @Test
    public void changeColorOfAllShapes_AND_buildStringShowingAllTheOldColors() {
        List<Shape> myShapes = Arrays.asList(new Shape(BLUE), new Shape(BLACK), new Shape(YELLOW));
        StringBuilder builder = new StringBuilder();

        Shapes.changeColorAndMakeStringOfOldColors(myShapes, RED, builder);

        assertThat(myShapes, hasSize(3));
        assertThat(myShapes, everyItem(hasColor(RED)));
        assertThat(builder.toString(), equalTo("[a BLUE shape][a BLACK shape][a YELLOW shape]"));
    }

    // ----- Test helpers -----

    private static Matcher<Shape> hasColor(Color color) {
        return FeatureMatchers.from(Matchers.is(color), "has color", "color", Shape::getColor);
    }
}
TOP

Related Classes of org.adoptopenjdk.lambda.tutorial.Exercise_1_Test

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.