/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */

import gls.CompilableTestSupport
import org.junit.jupiter.api.Test

final class DesignPatternsTest extends CompilableTestSupport {

    @Test
    void testAbstractFactory() {
        shouldCompile '''
            // tag::abstract_factory_example1[]
            class TwoupMessages {
                def welcome = 'Welcome to the twoup game, you start with $1000'
                def done = 'Sorry, you have no money left, goodbye'
            }

            class TwoupInputConverter {
                def convert(input) { input.toInteger() }
            }

            class TwoupControl {
                private money = 1000
                private random = new Random()
                private tossWasHead() {
                    def next = random.nextInt()
                    return next % 2 == 0
                }
                def moreTurns() {
                    if (money > 0) {
                        println "You have $money, how much would you like to bet?"
                        return true
                    }

                    false
                }
                def play(amount) {
                    def coin1 = tossWasHead()
                    def coin2 = tossWasHead()
                    if (coin1 && coin2) {
                        money += amount
                        println 'You win'
                    } else if (!coin1 && !coin2) {
                        money -= amount
                        println 'You lose'
                    } else {
                        println 'Draw'
                    }
                }
            }
            // end::abstract_factory_example1[]

            // tag::abstract_factory_example2[]
            class GuessGameMessages {
                def welcome = 'Welcome to the guessing game, my secret number is between 1 and 100'
                def done = 'Correct'
            }

            class GuessGameInputConverter {
                def convert(input) { input.toInteger() }
            }

            class GuessGameControl {
                private lower = 1
                private upper = 100
                private guess = new Random().nextInt(upper - lower) + lower
                def moreTurns() {
                    def done = (lower == guess || upper == guess)
                    if (!done) {
                        println "Enter a number between $lower and $upper"
                    }

                    !done
                }
                def play(nextGuess) {
                    if (nextGuess <= guess) {
                        lower = [lower, nextGuess].max()
                    }
                    if (nextGuess >= guess) {
                        upper = [upper, nextGuess].min()
                    }
                }
            }
            // end::abstract_factory_example2[]

            // tag::abstract_factory_code[]
            def guessFactory = [messages: GuessGameMessages, control: GuessGameControl, converter: GuessGameInputConverter]
            def twoupFactory = [messages: TwoupMessages, control: TwoupControl, converter: TwoupInputConverter]

            class GameFactory {
                def static factory
                def static getMessages() { return factory.messages.newInstance() }
                def static getControl() { return factory.control.newInstance() }
                def static getConverter() { return factory.converter.newInstance() }
            }
            // end::abstract_factory_code[]

            // tag::abstract_factory_usage[]
            GameFactory.factory = twoupFactory
            def messages = GameFactory.messages
            def control = GameFactory.control
            def converter = GameFactory.converter
            println messages.welcome
            def reader = new BufferedReader(new InputStreamReader(System.in))
            while (control.moreTurns()) {
                def input = reader.readLine().trim()
                control.play(converter.convert(input))
            }
            println messages.done
            // end::abstract_factory_usage[]
        '''
    }

    @Test
    void testAdapterDelegation() {
        shouldCompile '''
            // tag::adapter_delegation_classes[]
            class SquarePeg {
                def width
            }

            class RoundPeg {
                def radius
            }

            class RoundHole {
                def radius
                def pegFits(peg) {
                    peg.radius <= radius
                }
                String toString() { "RoundHole with radius $radius" }
            }
            // end::adapter_delegation_classes[]

            // tag::adapter_delegation_code[]
            class SquarePegAdapter {
                def peg
                def getRadius() {
                    Math.sqrt(((peg.width / 2) ** 2) * 2)
                }
                String toString() {
                    "SquarePegAdapter with peg width $peg.width (and notional radius $radius)"
                }
            }
            // end::adapter_delegation_code[]

            // tag::adapter_delegation_usage[]
            def hole = new RoundHole(radius: 4.0)
            (4..7).each { w ->
                def peg = new SquarePegAdapter(peg: new SquarePeg(width: w))
                if (hole.pegFits(peg)) {
                    println "peg $peg fits in hole $hole"
                } else {
                    println "peg $peg does not fit in hole $hole"
                }
            }
            // end::adapter_delegation_usage[]
        '''
    }

    @Test
    void testAdapterInheritanceClosuresExpandoMetaClass() {
        shouldCompile '''
            // tag::adapter_inheritance_classes[]
            class SquarePeg {
                def width
            }

            class RoundPeg {
                def radius
            }

            class RoundHole {
                def radius
                def pegFits(peg) {
                    peg.radius <= radius
                }
                String toString() { "RoundHole with radius $radius" }
            }
            // end::adapter_inheritance_classes[]

            // tag::adapter_inheritance_code[]
            class SquarePegAdapter extends SquarePeg {
                def getRadius() {
                    Math.sqrt(((width / 2) ** 2) * 2)
                }
                String toString() {
                    "SquarePegAdapter with width $width (and notional radius $radius)"
                }
            }
            // end::adapter_inheritance_code[]

            // tag::adapter_inheritance_usage[]
            def hole = new RoundHole(radius: 4.0)
            (4..7).each { w ->
                def peg = new SquarePegAdapter(width: w)
                if (hole.pegFits(peg)) {
                    println "peg $peg fits in hole $hole"
                } else {
                    println "peg $peg does not fit in hole $hole"
                }
            }
            // end::adapter_inheritance_usage[]

            // tag::adapter_closure_interface[]
            interface RoundThing {
                def getRadius()
            }
            // end::adapter_closure_interface[]

            // tag::adapter_closure_define[]
            def adapter = {
                p -> [getRadius: { Math.sqrt(((p.width / 2) ** 2) * 2) }] as RoundThing
            }
            // end::adapter_closure_define[]

            def isoHelper = {
                // tag::adapter_closure_usage[]
                def peg = new SquarePeg(width: 4)
                if (hole.pegFits(adapter(peg))) {
                    // ... as before
                }
                // end::adapter_closure_usage[]
            }

            def isoHelper2 = {
                // tag::adapter_expando_meta_class[]
                def peg = new SquarePeg(width: 4)
                peg.metaClass.radius = Math.sqrt(((peg.width / 2) ** 2) * 2)
                // end::adapter_expando_meta_class[]
            }
        '''
    }

    @Test
    void testBouncerNullCheck() {
        shouldCompile '''
            // tag::bouncer_null_check[]
            class NullChecker {
                static check(name, arg) {
                    if (arg == null) {
                        throw new IllegalArgumentException(name + ' is null')
                    }
                }
            }
            // end::bouncer_null_check[]

            class Test1 {
                // tag::bouncer_null_check_usage[]
                void doStuff(String name, Object value) {
                    NullChecker.check('name', name)
                    NullChecker.check('value', value)
                    // do stuff
                }
                // end::bouncer_null_check_usage[]
            }

            class Test2 {
                // tag::bouncer_null_check_usage_groovy_way[]
                void doStuff(String name, Object value) {
                    assert name != null, 'name should not be null'
                    assert value != null, 'value should not be null'
                    // do stuff
                }
                // end::bouncer_null_check_usage_groovy_way[]
            }
        '''
    }

    @Test
    void testBouncerValidation() {
        shouldCompile '''
            // tag::bouncer_validation[]
            class NumberChecker {
                static final String NUMBER_PATTERN = "\\\\d+(\\\\.\\\\d+(E-?\\\\d+)?)?"
                static isNumber(str) {
                    if (!str ==~ NUMBER_PATTERN) {
                        throw new IllegalArgumentException("Argument '$str' must be a number")
                    }
                }
                static isNotZero(number) {
                    if (number == 0) {
                        throw new IllegalArgumentException('Argument must not be 0')
                    }
                }
            }
            // end::bouncer_validation[]

            // tag::bouncer_validation_usage[]
            def stringDivide(String dividendStr, String divisorStr) {
                NumberChecker.isNumber(dividendStr)
                NumberChecker.isNumber(divisorStr)
                def dividend = dividendStr.toDouble()
                def divisor = divisorStr.toDouble()
                NumberChecker.isNotZero(divisor)
                dividend / divisor
            }

            println stringDivide('1.2E2', '3.0')
            // => 40.0
            // end::bouncer_validation_usage[]

            class Test {
                // tag::bouncer_validation_usage_groovy_way[]
                def stringDivide(String dividendStr, String divisorStr) {
                    assert dividendStr =~ NumberChecker.NUMBER_PATTERN
                    assert divisorStr =~ NumberChecker.NUMBER_PATTERN
                    def dividend = dividendStr.toDouble()
                    def divisor = divisorStr.toDouble()
                    assert divisor != 0, 'Divisor must not be 0'
                    dividend / divisor
                }
                // end::bouncer_validation_usage_groovy_way[]
            }
        '''
    }

    @Test
    void testCommand() {
        shouldCompile '''
            // tag::command_traditional[]
            interface Command {
                void execute()
            }

            // invoker class
            class Switch {
                private final Map<String, Command> commandMap = new HashMap<>()

                void register(String commandName, Command command) {
                    commandMap[commandName] = command
                }

                void execute(String commandName) {
                    Command command = commandMap[commandName]
                    if (!command) {
                        throw new IllegalStateException("no command registered for " + commandName)
                    }
                    command.execute()
                }
            }

            // receiver class
            class Light {
                void turnOn() {
                    println "The light is on"
                }

                void turnOff() {
                    println "The light is off"
                }
            }

            class SwitchOnCommand implements Command {
                Light light

                @Override // Command
                void execute() {
                    light.turnOn()
                }
            }

            class SwitchOffCommand implements Command {
                Light light

                @Override // Command
                void execute() {
                    light.turnOff()
                }
            }

            Light lamp = new Light()
            Command switchOn = new SwitchOnCommand(light: lamp)
            Command switchOff = new SwitchOffCommand(light: lamp)

            Switch mySwitch = new Switch()
            mySwitch.register("on", switchOn)
            mySwitch.register("off", switchOff)

            mySwitch.execute("on")
            mySwitch.execute("off")
            // end::command_traditional[]
        '''
        shouldCompile '''
            // tag::command_closures[]
            interface Command {
                void execute()
            }

            // invoker class
            class Switch {
                private final Map<String, Command> commandMap = [:]

                void register(String commandName, Command command) {
                    commandMap[commandName] = command
                }

                void execute(String commandName) {
                    Command command = commandMap[commandName]
                    if (!command) {
                        throw new IllegalStateException("no command registered for $commandName")
                    }
                    command.execute()
                }
            }

            // receiver class
            class Light {
                void turnOn() {
                    println 'The light is on'
                }

                void turnOff() {
                    println 'The light is off'
                }
            }

            Light lamp = new Light()

            Switch mySwitch = new Switch()
            mySwitch.register("on", lamp.&turnOn)       // <1>
            mySwitch.register("off", lamp.&turnOff)     // <1>

            mySwitch.execute("on")
            mySwitch.execute("off")
            // end::command_closures[]
        '''
        shouldCompile '''
            // tag::command_lambda[]
            class Light {
                void turnOn() {
                    println 'The light is on'
                }

                void turnOff() {
                    println 'The light is off'
                }
            }

            class Door {
                static void unlock() {
                    println 'The door is unlocked'
                }
            }

            Light lamp = new Light()
            Map<String, Runnable> mySwitch = [
                on: lamp::turnOn,
                off: lamp::turnOff,
                unlock: Door::unlock
            ]

            mySwitch.on()
            mySwitch.off()
            mySwitch.unlock()
            // end::command_lambda[]
            // tag::command_lambda_variant[]
            // ...
            List<Runnable> tasks = [lamp::turnOn, lamp::turnOff, Door::unlock]
            tasks.each{ it.run() }
            // end::command_lambda_variant[]
        '''
    }

    @Test
    void testChainOfResponsibility() {
        shouldCompile '''
            // tag::chain_of_responsibility[]
            class UnixLister {
                private nextInLine
                UnixLister(next) { nextInLine = next }
                def listFiles(dir) {
                    if (System.getProperty('os.name') == 'Linux') {
                        println "ls $dir".execute().text
                    } else {
                        nextInLine.listFiles(dir)
                    }
                }
            }

            class WindowsLister {
                private nextInLine
                WindowsLister(next) { nextInLine = next }
                def listFiles(dir) {
                    if (System.getProperty('os.name').startsWith('Windows')) {
                        println "cmd.exe /c dir $dir".execute().text
                    } else {
                        nextInLine.listFiles(dir)
                    }
                }
            }

            class DefaultLister {
                def listFiles(dir) {
                    new File(dir).eachFile { f -> println f }
                }
            }

            def lister = new UnixLister(new WindowsLister(new DefaultLister()))

            lister.listFiles('Downloads')
            // end::chain_of_responsibility[]
        '''
        shouldCompile '''
            // tag::chain_of_responsibility_elvis[]
            String unixListFiles(dir) {
                if (System.getProperty('os.name') == 'Linux') {
                    "ls $dir".execute().text
                }
            }

            String windowsListFiles(dir) {
                if (System.getProperty('os.name').startsWith('Windows')) {
                    "cmd.exe /c dir $dir".execute().text
                }
            }

            String defaultListFiles(dir) {
                new File(dir).listFiles().collect{ f -> f.name }.join('\\n')
            }

            def dir = 'Downloads'
            println unixListFiles(dir) ?: windowsListFiles(dir) ?: defaultListFiles(dir)
            // end::chain_of_responsibility_elvis[]
        '''
        shouldCompile '''
            // tag::chain_of_responsibility_switch[]
            String listFiles(dir) {
                switch(dir) {
                case { System.getProperty('os.name') == 'Linux' }:
                    return "ls $dir".execute().text
                case { System.getProperty('os.name').startsWith('Windows') }:
                    return "cmd.exe /c dir $dir".execute().text
                default:
                    new File(dir).listFiles().collect{ f -> f.name }.join('\\n')
                }
            }

            println listFiles('Downloads')
            // end::chain_of_responsibility_switch[]
        '''
        shouldCompile '''
            // tag::chain_of_responsibility_lambda[]
            Optional<String> unixListFiles(String dir) {
                Optional.ofNullable(dir)
                    .filter(d -> System.getProperty('os.name') == 'Linux')
                    .map(d -> "ls $d".execute().text)
            }

            Optional<String> windowsListFiles(String dir) {
                Optional.ofNullable(dir)
                    .filter(d -> System.getProperty('os.name').startsWith('Windows'))
                    .map(d -> "cmd.exe /c dir $d".execute().text)
            }

            Optional<String> defaultListFiles(String dir) {
                Optional.ofNullable(dir)
                    .map(d -> new File(d).listFiles().collect{ f -> f.name }.join('\\n'))
            }

            def dir = 'Downloads'
            def handlers = [this::unixListFiles, this::windowsListFiles, this::defaultListFiles]
            println handlers.stream()
                .map(f -> f(dir))
                .filter(Optional::isPresent)
                .map(Optional::get)
                .findFirst()
                .get()
            // end::chain_of_responsibility_lambda[]
        '''
        shouldCompile '''
            // tag::chain_of_responsibility_shape[]
            import static Math.PI as π
            abstract class Shape {
                String name
            }
            class Polygon extends Shape {
                String name
                double lengthSide
                int numSides
            }
            class Circle extends Shape {
                double radius
            }

            class CircleAreaCalculator {
                def next
                def area(shape) {
                    if (shape instanceof Circle) {            // <1>
                        return shape.radius ** 2 * π
                    } else {
                        next.area(shape)
                    }
                }
            }
            class SquareAreaCalculator {
                def next
                def area(shape) {
                    if (shape instanceof Polygon && shape.numSides == 4) {      // <1>
                        return shape.lengthSide ** 2
                    } else {
                        next.area(shape)
                    }
                }
            }
            class DefaultAreaCalculator {
                def area(shape) {
                    throw new IllegalArgumentException("Don't know how to calculate area for $shape")
                }
            }

            def chain = new CircleAreaCalculator(next: new SquareAreaCalculator(next: new DefaultAreaCalculator()))
            def shapes = [
                new Circle(name: 'Circle', radius: 5.0),
                new Polygon(name: 'Square', lengthSide: 10.0, numSides: 4)
            ]
            shapes.each { println chain.area(it) }
            // end::chain_of_responsibility_shape[]
        '''
        shouldCompile '''
            import static Math.PI as π
            abstract class Shape {
            }
            class Polygon extends Shape {
                double lengthSide
                int numSides
            }
            class Circle extends Shape {
                double radius
            }
            // tag::chain_of_responsibility_shape_multimethods[]
            // ...
            class Square extends Polygon {
                // ...
            }

            double area(Circle c) {
                c.radius ** 2 * π
            }

            double area(Square s) {
                s.lengthSide ** 2
            }

            def shapes = [
                new Circle(radius: 5.0),
                new Square(lengthSide: 10.0, numSides: 4)
            ]
            shapes.each { println area(it) }
            // end::chain_of_responsibility_shape_multimethods[]
        '''
        shouldCompile '''
            // tag::chain_of_responsibility_shape_oo[]
            import static Math.PI as π
            interface Shape {
                double area()
            }
            abstract class Polygon implements Shape {
                double lengthSide
                int numSides
                abstract double area()
            }
            class Circle implements Shape {
                double radius
                double area() {
                    radius ** 2 * π
                }
            }
            class Square extends Polygon {
                // ...
                double area() {
                    lengthSide ** 2
                }
            }

            def shapes = [
                new Circle(radius: 5.0),
                new Square(lengthSide: 10.0, numSides: 4)
            ]
            shapes.each { println it.area() }
            // end::chain_of_responsibility_shape_oo[]
        '''
    }

    @Test
    void testCompositeCode() {
        shouldCompile '''
            // tag::composite_code[]
            abstract class Component {
                def name
                def toString(indent) {
                    ("-" * indent) + name
                }
            }

            class Composite extends Component {
                private children = []
                def toString(indent) {
                    def s = super.toString(indent)
                    children.each { child ->
                        s += "\\n" + child.toString(indent + 1)
                    }
                    s
                }
                def leftShift(component) {
                    children << component
                }
            }

            class Leaf extends Component { }

            def root = new Composite(name: "root")
            root << new Leaf(name: "leaf A")
            def comp = new Composite(name: "comp B")
            root << comp
            root << new Leaf(name: "leaf C")
            comp << new Leaf(name: "leaf B1")
            comp << new Leaf(name: "leaf B2")
            println root.toString(0)
            // end::composite_code[]
        '''
    }

    @Test
    void testDecoratorLogger() {
        shouldCompile '''
            // tag::decorator_logger_class[]
            class Logger {
                def log(String message) {
                    println message
                }
            }
            // end::decorator_logger_class[]

            // tag::decorator_traditional_classes[]
            class TimeStampingLogger extends Logger {
                private Logger logger
                TimeStampingLogger(logger) {
                    this.logger = logger
                }
                def log(String message) {
                    def now = Calendar.instance
                    logger.log("$now.time: $message")
                }
            }

            class UpperLogger extends Logger {
                private Logger logger
                UpperLogger(logger) {
                    this.logger = logger
                }
                def log(String message) {
                    logger.log(message.toUpperCase())
                }
            }
            // end::decorator_traditional_classes[]

            // tag::decorator_dynamic_behaviour_class[]
            class GenericLowerDecorator {
                private delegate
                GenericLowerDecorator(delegate) {
                    this.delegate = delegate
                }
                def invokeMethod(String name, args) {
                    def newargs = args.collect { arg ->
                        if (arg instanceof String) {
                            return arg.toLowerCase()
                        } else {
                            return arg
                        }
                    }
                    delegate.invokeMethod(name, newargs)
                }
            }
            // end::decorator_dynamic_behaviour_class[]

            def separateHelper = {
                // tag::decorator_traditional_usage[]
                def logger = new UpperLogger(new TimeStampingLogger(new Logger()))
                logger.log("G'day Mate")
                // => Tue May 22 07:13:50 EST 2007: G'DAY MATE
                // end::decorator_traditional_usage[]

                // tag::decorator_traditional_usage2[]
                logger = new TimeStampingLogger(new UpperLogger(new Logger()))
                logger.log('Hi There')
                // => TUE MAY 22 07:13:50 EST 2007: HI THERE
                // end::decorator_traditional_usage2[]

                // tag::decorator_dynamic_behaviour_usage[]
                logger = new GenericLowerDecorator(new TimeStampingLogger(new Logger()))
                logger.log('IMPORTANT Message')
                // => Tue May 22 07:27:18 EST 2007: important message
                // end::decorator_dynamic_behaviour_usage[]
            }

            // tag::decorator_runtime_behaviour[]
            // current mechanism to enable ExpandoMetaClass
            GroovySystem.metaClassRegistry.metaClassCreationHandle = new ExpandoMetaClassCreationHandle()

            def logger = new Logger()
            logger.metaClass.log = { String m -> println 'message: ' + m.toUpperCase() }
            logger.log('x')
            // => message: X
            // end::decorator_runtime_behaviour[]
        '''
        shouldCompile '''
            // tag::decorating_logger_closure[]
            class DecoratingLogger {
                def decoration = Closure.IDENTITY

                def log(String message) {
                    println decoration(message)
                }
            }

            def upper = { it.toUpperCase() }
            def stamp = { "$Calendar.instance.time: $it" }
            def logger = new DecoratingLogger(decoration: stamp << upper)
            logger.log("G'day Mate")
            // Sat Aug 29 15:28:29 AEST 2020: G'DAY MATE
            // end::decorating_logger_closure[]
        '''
        shouldCompile '''
            // tag::decorating_logger_lambda[]
            import java.util.function.Function

            class DecoratingLogger {
                Function<String, String> decoration = Function.identity()

                def log(String message) {
                    println decoration.apply(message)
                }
            }

            Function<String, String> upper = s -> s.toUpperCase()
            Function<String, String> stamp = s -> "$Calendar.instance.time: $s"
            def logger = new DecoratingLogger(decoration: upper.andThen(stamp))
            logger.log("G'day Mate")
            // => Sat Aug 29 15:38:28 AEST 2020: G'DAY MATE
            // end::decorating_logger_lambda[]
        '''
    }

    @Test
    void testDecoratorCalc() {
        shouldCompile '''
            // tag::decorator_calc_class[]
            class Calc {
                def add(a, b) { a + b }
            }
            // end::decorator_calc_class[]

            // tag::decorator_tracing_decorator[]
            class TracingDecorator {
                private delegate
                TracingDecorator(delegate) {
                    this.delegate = delegate
                }
                def invokeMethod(String name, args) {
                    println "Calling $name$args"
                    def before = System.currentTimeMillis()
                    def result = delegate.invokeMethod(name, args)
                    println "Got $result in ${System.currentTimeMillis()-before} ms"
                    result
                }
            }
            // end::decorator_tracing_decorator[]

            // tag::decorator_tracing_decorator_usage[]
            def tracedCalc = new TracingDecorator(new Calc())
            assert 15 == tracedCalc.add(3, 12)
            // end::decorator_tracing_decorator_usage[]

            // tag::decorator_interceptor[]
            class TimingInterceptor extends TracingInterceptor {
                private beforeTime
                def beforeInvoke(object, String methodName, Object[] arguments) {
                    super.beforeInvoke(object, methodName, arguments)
                    beforeTime = System.currentTimeMillis()
                }
                Object afterInvoke(Object object, String methodName, Object[] arguments, Object result) {
                    super.afterInvoke(object, methodName, arguments, result)
                    def duration = System.currentTimeMillis() - beforeTime
                    writer.write("Duration: $duration ms\\n")
                    writer.flush()
                    result
                }
            }
            // end::decorator_interceptor[]

            // tag::decorator_interceptor_usage[]
            def proxy = ProxyMetaClass.getInstance(Calc)
            proxy.interceptor = new TimingInterceptor()
            proxy.use {
                assert 7 == new Calc().add(1, 6)
            }
            // end::decorator_interceptor_usage[]
        '''
    }

    @Test
    void testDecoratorSql() {
        shouldCompile '''
            @GrabExclude('org.codehaus.groovy:groovy-all')
            @Grab('org.apache.groovy:groovy-sql:5.0.4')
            import groovy.sql.Sql
            import java.lang.reflect.InvocationHandler
            import java.sql.Connection

            // tag::decorator_reflect_proxy[]
            protected Sql getGroovySql() {
                final Connection con = session.connection()
                def invoker = { object, method, args ->
                    if (method.name == "close") {
                        log.debug("ignoring call to Connection.close() for use by groovy.sql.Sql")
                    } else {
                        log.trace("delegating $method")
                        return con.invokeMethod(method.name, args)
                    }
                } as InvocationHandler;
                def proxy = Proxy.newProxyInstance( getClass().getClassLoader(), [Connection] as Class[], invoker )
                return new Sql(proxy)
            }
            // end::decorator_reflect_proxy[]
        '''
    }

    @Test
    void testDecoratorSpring() {
        shouldCompile '''
            package util // to match bean wiring
            // tag::decorator_spring_calc[]
            interface Calc {
                def add(a, b)
            }
            // end::decorator_spring_calc[]

            // tag::decorator_spring_calc_impl[]
            class CalcImpl implements Calc {
                def add(a, b) { a + b }
            }
            // end::decorator_spring_calc_impl[]

            // tag::decorator_spring_context[]
            @Grab('org.springframework:spring-context:5.2.8.RELEASE')
            import org.springframework.context.support.ClassPathXmlApplicationContext

            def ctx = new ClassPathXmlApplicationContext('beans.xml')
            def calc = ctx.getBean('calc')
            println calc.add(3, 25)
            // end::decorator_spring_context[]
        '''
    }

    @Test
    void testDecoratorAsync() {
        shouldCompile '''
            // tag::decorator_async[]
            import groovy.concurrent.Awaitable

            interface Document {
                void print()
                String getText()
            }

            class DocumentImpl implements Document {
                def document
                void print() { println document }
                String getText() { document }
            }

            def words(String text) {
                text.replaceAll('[^a-zA-Z]', ' ').trim().split("\\\\s+")*.toLowerCase()
            }

            def avgWordLength = {
                def words = words(it.text)
                sprintf "Avg Word Length: %4.2f", words*.size().sum() / words.size()
            }
            def modeWord = {
                def wordGroups = words(it.text).groupBy {it}.collectEntries { k, v -> [k, v.size()] }
                def maxSize = wordGroups*.value.max()
                def maxWords = wordGroups.findAll { it.value == maxSize }
                "Mode Word(s): ${maxWords*.key.join(', ')} ($maxSize occurrences)"
            }
            def wordCount = { d -> "Word Count: " + words(d.text).size() }

            def asyncDecorator(Document d, Closure c) {
                ProxyGenerator.INSTANCE.instantiateDelegate([print: {
                    def result = Awaitable.go { c(d) }
                    d.print()
                    println await(result)
                }], [Document], d)
            }

            Document d = asyncDecorator(asyncDecorator(asyncDecorator(
                    new DocumentImpl(document:"This is the file with the words in it\\n\\t\\nDo you see the words?\\n"),
            //        new DocumentImpl(document: new File('AsyncDecorator.groovy').text),
                    wordCount), modeWord), avgWordLength)
            d.print()
            // end::decorator_async[]
        '''
    }

    @Test
    void testDelegationExpandoMetaClass() {
        shouldCompile '''
            // tag::delegation_delegator[]
            class Delegator {
                private targetClass
                private delegate
                Delegator(targetClass, delegate) {
                    this.targetClass = targetClass
                    this.delegate = delegate
                }
                def delegate(String methodName) {
                    delegate(methodName, methodName)
                }
                def delegate(String methodName, String asMethodName) {
                    targetClass.metaClass."$asMethodName" = delegate.&"$methodName"
                }
                def delegateAll(String[] names) {
                    names.each { delegate(it) }
                }
                def delegateAll(Map names) {
                    names.each { k, v -> delegate(k, v) }
                }
                def delegateAll() {
                    delegate.class.methods*.name.each { delegate(it) }
                }
            }
            // end::delegation_delegator[]

            // tag::delegation_classes[]
            class Person {
                String name
            }

            class MortgageLender {
                def borrowAmount(amount) {
                   "borrow \\$$amount"
                }
                def borrowFor(thing) {
                   "buy \\$thing"
                }
            }

            def lender = new MortgageLender()

            def delegator = new Delegator(Person, lender)
            // end::delegation_classes[]

            // tag::delegation_usage[]
            delegator.delegate 'borrowFor'
            delegator.delegate 'borrowAmount', 'getMoney'

            def p = new Person()

            println p.borrowFor('present')   // => buy present
            println p.getMoney(50)
            // end::delegation_usage[]

            // tag::delegation_usage2[]
            delegator.delegateAll 'borrowFor', 'borrowAmount'
            // end::delegation_usage2[]

            // tag::delegation_usage3[]
            delegator.delegateAll()
            // end::delegation_usage3[]

            // tag::delegation_usage4[]
            delegator.delegateAll borrowAmount:'getMoney', borrowFor:'getThing'
            // end::delegation_usage4[]
        '''
    }

    @Test
    void testDelegationAnnotation() {
        shouldCompile '''
            // tag::delegation_annotation[]
            class Person {
                def name
                @Delegate MortgageLender mortgageLender = new MortgageLender()
            }

            class MortgageLender {
                def borrowAmount(amount) {
                   "borrow \\$$amount"
                }
                def borrowFor(thing) {
                   "buy $thing"
                }
            }

            def p = new Person()

            assert "buy present" == p.borrowFor('present')
            assert "borrow \\$50" == p.borrowAmount(50)
            // end::delegation_annotation[]
        '''
    }

    @Test
    void testFlyweight() {
        shouldCompile '''
            // tag::flyweight_boeing797[]
            class Boeing797 {
                def wingspan = '80.8 m'
                def capacity = 1000
                def speed = '1046 km/h'
                def range = '14400 km'
                // ...
            }
            // end::flyweight_boeing797[]

            // tag::flyweight_airbus380[]
            class Airbus380 {
                def wingspan = '79.8 m'
                def capacity = 555
                def speed = '912 km/h'
                def range = '10370 km'
                // ...
            }
            // end::flyweight_airbus380[]

            // tag::flyweight_factory[]
            class FlyweightFactory {
                static instances = [797: new Boeing797(), 380: new Airbus380()]
            }

            class Aircraft {
                private type         // intrinsic state
                private assetNumber  // extrinsic state
                private bought       // extrinsic state
                Aircraft(typeCode, assetNumber, bought) {
                    type = FlyweightFactory.instances[typeCode]
                    this.assetNumber = assetNumber
                    this.bought = bought
                }
                def describe() {
                    println """
                    Asset Number: $assetNumber
                    Capacity: $type.capacity people
                    Speed: $type.speed
                    Range: $type.range
                    Bought: $bought
                    """
                }
            }

            def fleet = [
                new Aircraft(380, 1001, '10-May-2007'),
                new Aircraft(380, 1002, '10-Nov-2007'),
                new Aircraft(797, 1003, '10-May-2008'),
                new Aircraft(797, 1004, '10-Nov-2008')
            ]

            fleet.each { p -> p.describe() }
            // end::flyweight_factory[]
        '''
    }

    @Test
    void testIterator() {
        shouldCompile '''
            // tag::iterator_example[]
            def printAll(container) {
                for (item in container) { println item }
            }

            def numbers = [ 1,2,3,4 ]
            def months = [ Mar:31, Apr:30, May:31 ]
            def colors = [ java.awt.Color.BLACK, java.awt.Color.WHITE ]
            printAll numbers
            printAll months
            printAll colors
            // end::iterator_example[]

            // tag::iterator_example2[]
            colors.eachWithIndex { item, pos ->
                println "Position $pos contains '$item'"
            }
            // end::iterator_example2[]
        '''
    }

    @Test
    void testLoanMyResource() {
        shouldCompile '''
            // tag::loan_my_resource_example[]
            def f = new File('junk.txt')
            f.withPrintWriter { pw ->
                pw.println(new Date())
                pw.println(this.class.name)
            }
            println f.size()
            // => 42
            // end::loan_my_resource_example[]

            // tag::loan_my_resource_example2[]
            f.eachLine { line ->
                println line
            }
            // =>
            // Mon Jun 18 22:38:17 EST 2007
            // RunPattern
            // end::loan_my_resource_example2[]

            // tag::loan_my_resource_example3[]
            def reader = f.newReader()
            reader.splitEachLine(' ') { wordList ->
                println wordList
            }
            reader.close()
            // =>
            // [ "Mon", "Jun", "18", "22:38:17", "EST", "2007" ]
            // [ "RunPattern" ]
            // end::loan_my_resource_example3[]

            // tag::loan_my_resource_example4[]
            def withListOfWordsForEachLine(File f, Closure c) {
                def r = f.newReader()
                try {
                    r.splitEachLine(' ', c)
                } finally {
                    r?.close()
                }
            }
            // end::loan_my_resource_example4[]

            // tag::loan_my_resource_example5[]
            withListOfWordsForEachLine(f) { wordList ->
                println wordList
            }
            // =>
            // [ "Mon", "Jun", "18", "22:38:17", "EST", "2007" ]
            // [ "RunPattern" ]
            // end::loan_my_resource_example5[]
        '''
    }

    @Test
    void testMonoids() {
        assertScript '''
        // tag::monoids_intro[]
        def nums = [1, 2, 3, 4]

        def sum = 0    // <1>
        for (num in nums) { sum += num }    // <2>
        assert sum == 10

        def product = 1    // <1>
        for (num in nums) { product *= num }    // <2>
        assert product == 24

        def letters = ['a', 'b', 'c']

        def concat = ''    // <1>
        for (letter in letters) { concat += letter }    // <2>
        assert concat == 'abc'
        // end::monoids_intro[]
        // tag::monoids_inject[]
        assert nums.inject(0){ total, next -> total + next } == 10
        assert nums.inject(1){ total, next -> total * next } == 24
        assert letters.inject(''){ total, next -> total + next } == 'abc'
        // end::monoids_inject[]
        // tag::monoids_lambdas[]
        assert nums.stream().reduce(0, (total, next) -> total + next) == 10
        assert nums.stream().reduce(1, (total, next) -> total * next) == 24
        assert letters.stream().reduce('', (total, next) -> total + next) == 'abc'
        // end::monoids_lambdas[]
        '''
        assertScript '''
        import groovy.concurrent.ParallelScope
        import groovy.concurrent.Pool

        // tag::monoids_parallel[]
        def nums = 10..16
        ParallelScope.withPool(Pool.cpu()) {
            assert 91 == nums.toList().injectParallel(0){ total, next -> total + next }
        }
        // end::monoids_parallel[]
        // tag::monoids_average_1to10[]
        assert (1..10).average() == 5.5
        // end::monoids_average_1to10[]
        // tag::monoids_average_0to10[]
        assert (0..10).average() == 5
        // end::monoids_average_0to10[]
        '''
        assertScript '''
        // tag::monoids_average_bad[]
        def avg = { a, b -> (a + b) / 2 }
        // end::monoids_average_bad[]
        // tag::monoids_average_assoc[]
        assert 6 == avg(avg(10, 2), 6)
        assert 7 == avg(10, avg(2, 6))
        // end::monoids_average_assoc[]
        '''
        assertScript '''
        // tag::monoids_average_split[]
        def nums = 1..10
        def total = nums.sum()
        def avg = total / nums.size()
        assert avg == 5.5
        // end::monoids_average_split[]
        import groovy.concurrent.ParallelScope
        import groovy.concurrent.Pool
        // tag::monoids_average_split_parallel[]
        ParallelScope.withPool(Pool.cpu()) {
            assert 5.5 == nums.toList().sumParallel{ a, b -> a + b } / nums.size()
        }
        // end::monoids_average_split_parallel[]
        '''
        assertScript '''
        def nums = 1..10
        // tag::monoids_average_reworked_simple[]
        def holder = nums
            .collect{ [it, 1] }
            .inject{ a, b -> [a[0] + b[0], a[1] + b[1]] }
        def avg = holder[0] / holder[1]
        assert avg == 5.5
        // end::monoids_average_reworked_simple[]
        '''
        assertScript '''
        import groovy.concurrent.ParallelScope
        import groovy.concurrent.Pool
        def nums = 1..10
        // tag::monoids_average_reworked_parallel[]
        class AverageHolder {
            int total
            int count
            AverageHolder plus(AverageHolder other) {
                return new AverageHolder(total: total + other.total,
                                         count: count + other.count)
            }
            static final AverageHolder ZERO =
                new AverageHolder(total: 0, count: 0)
        }

        def asHolder = {
            it instanceof Integer ? new AverageHolder(total: it, count : 1) : it
        }
        def pairwiseAggregate = { aggregate, next ->
            asHolder(aggregate) + asHolder(next)
        }
        ParallelScope.withPool(Pool.cpu()) {
            def holder = nums.toList().injectParallel(AverageHolder.ZERO, pairwiseAggregate)
            def avg = holder.with{ total / count }
            assert avg == 5.5
        }
        // end::monoids_average_reworked_parallel[]
        '''
    }

    @Test
    void testNullObjectSimpleExample() {
        shouldCompile '''
            // tag::null_object_simple_example[]
            class Job {
                def salary
            }

            class Person {
                def name
                def Job job
            }

            def people = [
                new Person(name: 'Tom', job: new Job(salary: 1000)),
                new Person(name: 'Dick', job: new Job(salary: 1200)),
            ]

            def biggestSalary = people.collect { p -> p.job.salary }.max()
            println biggestSalary
            // end::null_object_simple_example[]

            // tag::null_object_simple_example2[]
            people << new Person(name: 'Harry')
            // end::null_object_simple_example2[]

            // tag::null_object_simple_example3[]
            class NullJob extends Job { def salary = 0 }

            people << new Person(name: 'Harry', job: new NullJob())
            biggestSalary = people.collect { p -> p.job.salary }.max()
            println biggestSalary
            // end::null_object_simple_example3[]

            // tag::null_object_simple_example4[]
            people << new Person(name:'Harry')
            biggestSalary = people.collect { p -> p.job?.salary }.max()
            println biggestSalary
            // end::null_object_simple_example4[]
        '''
    }

    @Test
    void testNullObjectTreeExample() {
        shouldCompile '''
            // tag::null_object_tree_example[]
            class NullHandlingTree {
                def left, right, value

                def size() {
                    1 + (left ? left.size() : 0) + (right ? right.size() : 0)
                }

                def sum() {
                   value + (left ? left.sum() : 0) + (right ? right.sum() : 0)
                }

                def product() {
                   value * (left ? left.product() : 1) * (right ? right.product() : 1)
                }
            }

            def root = new NullHandlingTree(
                value: 2,
                left: new NullHandlingTree(
                    value: 3,
                    right: new NullHandlingTree(value: 4),
                    left: new NullHandlingTree(value: 5)
                )
            )

            println root.size()
            println root.sum()
            println root.product()
            // end::null_object_tree_example[]
        '''
    }

    @Test
    void testNullObjectTreeExample2() {
        shouldCompile '''
            // tag::null_object_tree_example2[]
            class Tree {
                def left = new NullTree(), right = new NullTree(), value

                def size() {
                    1 + left.size() + right.size()
                }

                def sum() {
                   value + left.sum() + right.sum()
                }

                def product() {
                   value * left.product() * right.product()
                }
            }

            class NullTree {
                def size() { 0 }
                def sum() { 0 }
                def product() { 1 }
            }

            def root = new Tree(
                value: 2,
                left: new Tree(
                    value: 3,
                    right: new Tree(value: 4),
                    left: new Tree(value: 5)
                )
            )

            println root.size()
            println root.sum()
            println root.product()
            // end::null_object_tree_example2[]
        '''
    }

    @Test
    void testObserverExample() {
        assertScript '''
            // tag::observer_classic[]
            interface Observer {
                void update(message)
            }

            class Subject {
                private List observers = []
                void register(observer) {
                    observers << observer
                }
                void unregister(observer) {
                    observers -= observer
                }
                void notifyAll(message) {
                    observers.each{ it.update(message) }
                }
            }

            class ConcreteObserver1 implements Observer {
                def messages = []
                void update(message) {
                    messages << message
                }
            }

            class ConcreteObserver2 implements Observer {
                def messages = []
                void update(message) {
                    messages << message.toUpperCase()
                }
            }

            def o1a = new ConcreteObserver1()
            def o1b = new ConcreteObserver1()
            def o2 = new ConcreteObserver2()
            def observers = [o1a, o1b, o2]
            new Subject().with {
                register(o1a)
                register(o2)
                notifyAll('one')
            }
            new Subject().with {
                register(o1b)
                register(o2)
                notifyAll('two')
            }
            def expected = [['one'], ['two'], ['ONE', 'TWO']]
            assert observers*.messages == expected
            // end::observer_classic[]
        '''
        assertScript '''
            // tag::observer_closures[]
            interface Observer {
                void update(message)
            }

            class Subject {
                private List observers = []
                void register(Observer observer) {
                    observers << observer
                }
                void unregister(observer) {
                    observers -= observer
                }
                void notifyAll(message) {
                    observers.each{ it.update(message) }
                }
            }

            def messages1a = [], messages1b = [], messages2 = []
            def o2 = { messages2 << it.toUpperCase() }
            new Subject().with {
                register{ messages1a << it }
                register(o2)
                notifyAll('one')
            }
            new Subject().with {
                register{ messages1b << it }
                register(o2)
                notifyAll('two')
            }
            def expected = [['one'], ['two'], ['ONE', 'TWO']]
            assert [messages1a, messages1b, messages2] == expected
            // end::observer_closures[]
        '''
        assertScript '''
            // tag::observer_lambdas[]
            import java.util.function.Consumer

            class Subject {
                private List<Consumer> observers = []
                void register(Consumer observer) {
                    observers << observer
                }
                void unregister(observer) {
                    observers -= observer
                }
                void notifyAll(message) {
                    observers.each{ it.accept(message) }
                }
            }

            def messages1a = [], messages1b = [], messages2 = []
            def o2 = { messages2 << it.toUpperCase() }
            new Subject().with {
                register(s -> messages1a << s)
                register(s -> messages2 << s.toUpperCase())
                notifyAll('one')
            }
            new Subject().with {
                register(s -> messages1b << s)
                register(s -> messages2 << s.toUpperCase())
                notifyAll('two')
            }
            def expected = [['one'], ['two'], ['ONE', 'TWO']]
            assert [messages1a, messages1b, messages2] == expected
            // end::observer_lambdas[]
        '''
        assertScript '''
            // tag::observer_bindable[]
            import groovy.beans.*
            import java.beans.*

            class PersonBean {
                @Bindable String first
                @Bindable String last
                @Vetoable Integer age
            }

            def messages = [:].withDefault{[]}
            new PersonBean().with {
                addPropertyChangeListener{ PropertyChangeEvent ev ->
                    messages[ev.propertyName] << "prop: $ev.newValue"
                }
                addVetoableChangeListener{ PropertyChangeEvent ev ->
                    def name = ev.propertyName
                    if (name == 'age' && ev.newValue > 40)
                        throw new PropertyVetoException()
                    messages[name] << "veto: $ev.newValue"
                }
                first = 'John'
                age = 35
                last = 'Smith'
                first = 'Jane'
                age = 42
            }

            def expected = [
                first:['prop: John', 'prop: Jane'],
                age:['veto: 35'],
                last:['prop: Smith']
            ]
            assert messages == expected
            // end::observer_bindable[]
        '''
    }

    @Test
    void testPimpMyLibraryExample() {
        shouldCompile '''
            // tag::pimp_my_library_example[]
            class EnhancedInteger {
                static boolean greaterThanAll(Integer self, Object[] others) {
                    greaterThanAll(self, others)
                }
                static boolean greaterThanAll(Integer self, others) {
                    others.every { self > it }
                }
            }
            // end::pimp_my_library_example[]

            // tag::pimp_my_library_example2[]
            use(EnhancedInteger) {
                assert 4.greaterThanAll(1, 2, 3)
                assert !5.greaterThanAll(2, 4, 6)
                assert 5.greaterThanAll(-4..4)
                assert 5.greaterThanAll([])
                assert !5.greaterThanAll([4, 5])
            }
            // end::pimp_my_library_example2[]
        '''
    }

    @Test
    void testProxyClient() {
        shouldCompile '''
            // tag::proxy_client[]
            class AccumulatorProxy {
                def accumulate(args) {
                    def result
                    def s = new Socket("localhost", 54321)
                    s.withObjectStreams { ois, oos ->
                        oos << args
                        result = ois.readObject()
                    }
                    s.close()
                    return result
                }
            }

            println new AccumulatorProxy().accumulate([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
            // => 55
            // end::proxy_client[]
        '''
    }

    @Test
    void testProxyServer() {
        shouldCompile '''
            // tag::proxy_server[]
            class Accumulator {
                def accumulate(args) {
                    args.inject(0) { total, arg -> total += arg }
                }
            }

            def port = 54321
            def accumulator = new Accumulator()
            def server = new ServerSocket(port)
            println "Starting server on port $port"
            while(true) {
                server.accept() { socket ->
                    socket.withObjectStreams { ois, oos ->
                        def args = ois.readObject()
                        oos << accumulator.accumulate(args)
                    }
                }
            }
            // end::proxy_server[]
        '''
    }

    @Test
    void testSingletonVoteCollector() {
        shouldCompile '''
            // tag::singleton_vote_collector[]
            class VoteCollector {
                def votes = 0
                private static final INSTANCE = new VoteCollector()
                static getInstance() { return INSTANCE }
                private VoteCollector() { }
                def display() { println "Collector:${hashCode()}, Votes:$votes" }
            }
            // end::singleton_vote_collector[]

            // tag::singleton_vote_collector_usage[]
            def collector = VoteCollector.instance
            collector.display()
            collector.votes++
            collector = null

            Thread.start{
                def collector2 = VoteCollector.instance
                collector2.display()
                collector2.votes++
                collector2 = null
            }.join()

            def collector3 = VoteCollector.instance
            collector3.display()
            // end::singleton_vote_collector_usage[]
        '''
    }

    @Test
    void testSingletonMetaProgramming() {
        shouldCompile '''
            // tag::singleton_meta_programming_classes[]
            class Calculator {
                private total = 0
                def add(a, b) { total++; a + b }
                def getTotalCalculations() { 'Total Calculations: ' + total }
                String toString() { 'Calc: ' + hashCode() }
            }

            class Client {
                def calc = new Calculator()
                def executeCalc(a, b) { calc.add(a, b) }
                String toString() { 'Client: ' + hashCode() }
            }
            // end::singleton_meta_programming_classes[]

            // tag::singleton_meta_programming_meta_class[]
            class CalculatorMetaClass extends MetaClassImpl {
                private static final INSTANCE = new Calculator()
                CalculatorMetaClass() { super(Calculator) }
                def invokeConstructor(Object[] arguments) { return INSTANCE }
            }

            def registry = GroovySystem.metaClassRegistry
            registry.setMetaClass(Calculator, new CalculatorMetaClass())
            // end::singleton_meta_programming_meta_class[]

            // tag::singleton_meta_programming_usage[]
            def client = new Client()
            assert 3 == client.executeCalc(1, 2)
            println "$client, $client.calc, $client.calc.totalCalculations"

            client = new Client()
            assert 4 == client.executeCalc(2, 2)
            println "$client, $client.calc, $client.calc.totalCalculations"
            // end::singleton_meta_programming_usage[]
        '''
    }

    @Test
    void testSingletonGuice() {
        shouldCompile '''
            // tag::singleton_guice[]
            @Grapes([@Grab('aopalliance:aopalliance:1.0'), @Grab('com.google.code.guice:guice:1.0')])
            import com.google.inject.*

            interface Calculator {
                def add(a, b)
            }

            class CalculatorImpl implements Calculator {
                private total = 0
                def add(a, b) { total++; a + b }
                def getTotalCalculations() { 'Total Calculations: ' + total }
                String toString() { 'Calc: ' + hashCode() }
            }

            class Client {
                @Inject Calculator calc
                def executeCalc(a, b) { calc.add(a, b) }
                String toString() { 'Client: ' + hashCode() }
            }

            def injector = Guice.createInjector (
                [configure: { binding ->
                    binding.bind(Calculator)
                           .to(CalculatorImpl)
                           .asEagerSingleton() } ] as Module
            )

            def client = injector.getInstance(Client)
            assert 3 == client.executeCalc(1, 2)
            println "$client, $client.calc, $client.calc.totalCalculations"

            client = injector.getInstance(Client)
            assert 4 == client.executeCalc(2, 2)
            println "$client, $client.calc, $client.calc.totalCalculations"
            // end::singleton_guice[]
        '''
    }

    @Test
    void testSingletonGuice2() {
        shouldCompile '''
            // tag::singleton_guice2[]
            @Grapes([@Grab('aopalliance:aopalliance:1.0'), @Grab('com.google.code.guice:guice:1.0')])
            import com.google.inject.*

            @ImplementedBy(CalculatorImpl)
            interface Calculator {
                // as before ...
            }

            @Singleton
            class CalculatorImpl implements Calculator {
                // as before ...
            }

            class Client {
                // as before ...
            }

            def injector = Guice.createInjector()

            // ...
            // end::singleton_guice2[]
        '''
    }

    @Test
    void testSingletonSpring() {
        shouldCompile '''
            // tag::singleton_spring[]
            @Grapes([@Grab('org.springframework:spring-core:5.2.8.RELEASE'), @Grab('org.springframework:spring-beans:5.2.8.RELEASE')])
            import org.springframework.beans.factory.support.*

            interface Calculator {
                def add(a, b)
            }

            class CalculatorImpl implements Calculator {
                private total = 0
                def add(a, b) { total++; a + b }
                def getTotalCalculations() { 'Total Calculations: ' + total }
                String toString() { 'Calc: ' + hashCode() }
            }

            class Client {
                Client(Calculator calc) { this.calc = calc }
                def calc
                def executeCalc(a, b) { calc.add(a, b) }
                String toString() { 'Client: ' + hashCode() }
            }

            // Here we 'wire' up our dependencies through the API. Alternatively,
            // we could use XML-based configuration or the Grails Bean Builder DSL.
            def factory = new DefaultListableBeanFactory()
            factory.registerBeanDefinition('calc', new RootBeanDefinition(CalculatorImpl))
            def beanDef = new RootBeanDefinition(Client, false)
            beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_AUTODETECT)
            factory.registerBeanDefinition('client', beanDef)

            def client = factory.getBean('client')
            assert 3 == client.executeCalc(1, 2)
            println "$client, $client.calc, $client.calc.totalCalculations"

            client = factory.getBean('client')
            assert 4 == client.executeCalc(2, 2)
            println "$client, $client.calc, $client.calc.totalCalculations"
            // end::singleton_spring[]
        '''
    }

    @Test
    void testStateExample() {
        shouldCompile '''
            // tag::state_example[]
            class Client {
                def context = new Context()
                def connect() {
                    context.state.connect()
                }
                def disconnect() {
                    context.state.disconnect()
                }
                def send_message(message) {
                    context.state.send_message(message)
                }
                def receive_message() {
                    context.state.receive_message()
                }
            }

            class Context {
                def state = new Offline(this)
            }

            class ClientState {
                def context
                ClientState(context) {
                    this.context = context
                    inform()
                }
            }

            class Offline extends ClientState {
                Offline(context) {
                    super(context)
                }
                def inform() {
                    println "offline"
                }
                def connect() {
                    context.state = new Online(context)
                }
                def disconnect() {
                    println "error: not connected"
                }
                def send_message(message) {
                    println "error: not connected"
                }
                def receive_message() {
                    println "error: not connected"
                }
            }

            class Online extends ClientState {
                Online(context) {
                    super(context)
                }
                def inform() {
                    println "connected"
                }
                def connect() {
                    println "error: already connected"
                }
                def disconnect() {
                    context.state = new Offline(context)
                }
                def send_message(message) {
                    println "\"$message\" sent"
                }
                def receive_message() {
                    println "message received"
                }
            }

            client = new Client()
            client.send_message("Hello")
            client.connect()
            client.send_message("Hello")
            client.connect()
            client.receive_message()
            client.disconnect()
            // end::state_example[]
        '''
    }

    @Test
    void testStateVariation1() {
        shouldCompile '''
            // tag::state_variation1_interface[]
            interface State {
                def connect()
                def disconnect()
                def send_message(message)
                def receive_message()
            }
            // end::state_variation1_interface[]
        '''
    }

    @Test
    void testStateVariation2() {
        shouldCompile '''
            interface State { }

            // tag::state_variation1_impl[]
            class Client implements State {
              // ... as before ...
            }

            class Online implements State {
              // ... as before ...
            }

            class Offline implements State {
              // ... as before ...
            }
            // end::state_variation1_impl[]
        '''
    }

    @Test
    void testStateVariation3() {
        shouldCompile '''
            // tag::state_variation2_classes[]
            abstract class InstanceProvider {
                static def registry = GroovySystem.metaClassRegistry
                static def create(objectClass, param) {
                    registry.getMetaClass(objectClass).invokeConstructor([param] as Object[])
                }
            }

            abstract class Context {
                private context
                protected setContext(context) {
                    this.context = context
                }
                def invokeMethod(String name, Object arg) {
                    context.invokeMethod(name, arg)
                }
                def startFrom(initialState) {
                    setContext(InstanceProvider.create(initialState, this))
                }
            }

            abstract class State {
                private client

                State(client) { this.client = client }

                def transitionTo(nextState) {
                    client.setContext(InstanceProvider.create(nextState, client))
                }
            }
            // end::state_variation2_classes[]

            // tag::state_variation2_impl[]
            class Client extends Context {
                Client() {
                    startFrom(Offline)
                }
            }

            class Offline extends State {
                Offline(client) {
                    super(client)
                    println "offline"
                }
                def connect() {
                    transitionTo(Online)
                }
                def disconnect() {
                    println "error: not connected"
                }
                def send_message(message) {
                    println "error: not connected"
                }
                def receive_message() {
                    println "error: not connected"
                }
            }

            class Online extends State {
                Online(client) {
                    super(client)
                    println "connected"
                }
                def connect() {
                    println "error: already connected"
                }
                def disconnect() {
                    transitionTo(Offline)
                }
                def send_message(message) {
                    println "\"$message\" sent"
                }
                def receive_message() {
                    println "message received"
                }
            }

            client = new Client()
            client.send_message("Hello")
            client.connect()
            client.send_message("Hello")
            client.connect()
            client.receive_message()
            client.disconnect()
            // end::state_variation2_impl[]
        '''
    }

    @Test
    void testStateVariation4() {
        shouldCompile '''
            // tag::state_variation31[]
            class Grammar {
                def fsm

                def event
                def fromState
                def toState

                Grammar(a_fsm) {
                    fsm = a_fsm
                }

                def on(a_event) {
                    event = a_event
                    this
                }

                def on(a_event, a_transitioner) {
                    on(a_event)
                    a_transitioner.delegate = this
                    a_transitioner.call()
                    this
                }

                def from(a_fromState) {
                    fromState = a_fromState
                    this
                }

                def to(a_toState) {
                    assert a_toState, "Invalid toState: $a_toState"
                    toState = a_toState
                    fsm.registerTransition(this)
                    this
                }

                def isValid() {
                    event && fromState && toState
                }

                public String toString() {
                    "$event: $fromState=>$toState"
                }
            }
            // end::state_variation31[]

            // tag::state_variation32[]
            class FiniteStateMachine {
                def transitions = [:]

                def initialState
                def currentState

                FiniteStateMachine(a_initialState) {
                    assert a_initialState, "You need to provide an initial state"
                    initialState = a_initialState
                    currentState = a_initialState
                }

                def record() {
                    Grammar.newInstance(this)
                }

                def reset() {
                    currentState = initialState
                }

                def isState(a_state) {
                    currentState == a_state
                }

                def registerTransition(a_grammar) {
                    assert a_grammar.isValid(), "Invalid transition ($a_grammar)"
                    def transition
                    def event = a_grammar.event
                    def fromState = a_grammar.fromState
                    def toState = a_grammar.toState

                    if (!transitions[event]) {
                        transitions[event] = [:]
                    }

                    transition = transitions[event]
                    assert !transition[fromState], "Duplicate fromState $fromState for transition $a_grammar"
                    transition[fromState] = toState
                }

                def fire(a_event) {
                    assert currentState, "Invalid current state '$currentState': passed into constructor"
                    assert transitions.containsKey(a_event), "Invalid event '$a_event', should be one of ${transitions.keySet()}"
                    def transition = transitions[a_event]
                    def nextState = transition[currentState]
                    assert nextState, "There is no transition from '$currentState' to any other state"
                    currentState = nextState
                    currentState
                }
            }
            // end::state_variation32[]
            // tag::state_variation33[]
            class StatePatternDslTest {
                private fsm

                void setUp() {
                    fsm = FiniteStateMachine.newInstance('offline')
                    def recorder = fsm.record()
                    recorder.on('connect').from('offline').to('online')
                    recorder.on('disconnect').from('online').to('offline')
                    recorder.on('send_message').from('online').to('online')
                    recorder.on('receive_message').from('online').to('online')
                }

                void testInitialState() {
                    assert fsm.isState('offline')
                }

                void testOfflineState() {
                    shouldFail{
                        fsm.fire('send_message')
                    }
                    shouldFail{
                        fsm.fire('receive_message')
                    }
                    shouldFail{
                        fsm.fire('disconnect')
                    }
                    assert 'online' == fsm.fire('connect')
                }

                void testOnlineState() {
                    fsm.fire('connect')
                    fsm.fire('send_message')
                    fsm.fire('receive_message')
                    shouldFail{
                        fsm.fire('connect')
                    }
                    assert 'offline' == fsm.fire('disconnect')
                }
            }
            // end::state_variation33[]
        '''
    }

    @Test
    void testStrategyTraditional() {
        assertScript '''
            // tag::strategy_traditional[]
            interface Calc {
                def execute(n, m)
            }

            class CalcByMult implements Calc {
                def execute(n, m) { n * m }
            }

            class CalcByManyAdds implements Calc {
                def execute(n, m) {
                    def result = 0
                    n.times{
                        result += m
                    }

                    result
                }
            }

            def sampleData = [
                [3, 4, 12],
                [5, -5, -25]
            ]

            Calc[] multiplicationStrategies = [
                new CalcByMult(),
                new CalcByManyAdds()
            ]

            sampleData.each{ data ->
                multiplicationStrategies.each { calc ->
                    assert data[2] == calc.execute(data[0], data[1])
                }
            }
            // end::strategy_traditional[]
        '''
    }

    @Test
    void testStrategyGroovyWay() {
        assertScript '''
            // tag::strategy_groovy_way[]
            def multiplicationStrategies = [
                { n, m -> n * m },
                { n, m -> def result = 0; n.times{ result += m }; result }
            ]

            def sampleData = [
                [3, 4, 12],
                [5, -5, -25]
            ]

            sampleData.each{ data ->
                multiplicationStrategies.each { calc ->
                    assert data[2] == calc(data[0], data[1])
                }
            }
            // end::strategy_groovy_way[]
        '''
    }

    @Test
    void testStrategyLambdaWithSAMInterface() {
        assertScript '''
            // tag::strategy_lambdas_with_explicit_interface[]
            interface Calc {
                def execute(n, m)
            }

            List<Calc> multiplicationStrategies = [
                (n, m) -> n * m,
                (n, m) -> { def result = 0; n.times{ result += m }; result }
            ]

            def sampleData = [
                [3, 4, 12],
                [5, -5, -25]
            ]

            sampleData.each{ data ->
                multiplicationStrategies.each { calc ->
                    assert data[2] == calc(data[0], data[1])
                }
            }
            // end::strategy_lambdas_with_explicit_interface[]
        '''
    }

    @Test
    void testStrategyLambdaBiFunction() {
        assertScript '''
            // tag::strategy_lambdas_using_bifunction[]
            import java.util.function.BiFunction

            List<BiFunction<Integer, Integer, Integer>> multiplicationStrategies = [
                (n, m) -> n * m,
                (n, m) -> { def result = 0; n.times{ result += m }; result }
            ]

            def sampleData = [
                [3, 4, 12],
                [5, -5, -25]
            ]

            sampleData.each{ data ->
                multiplicationStrategies.each { calc ->
                    assert data[2] == calc(data[0], data[1])
                }
            }
            // end::strategy_lambdas_using_bifunction[]
        '''
    }

    @Test
    void testTemplateMethod() {
        assertScript '''
            // tag::template_method_example[]
            abstract class Accumulator {
                protected initial
                abstract doAccumulate(total, v)
                def accumulate(values) {
                    def total = initial
                    values.each { v -> total = doAccumulate(total, v) }
                    total
                }
            }

            class Sum extends Accumulator {
                def Sum() { initial = 0 }
                def doAccumulate(total, v) { total + v }
            }

            class Product extends Accumulator {
                def Product() { initial = 1 }
                def doAccumulate(total, v) { total * v }
            }

            assert 10 == new Sum().accumulate([1,2,3,4])
            assert 24 == new Product().accumulate([1,2,3,4])
            // end::template_method_example[]
        '''
    }

    @Test
    void testTemplateMethod2() {
        assertScript '''
            // tag::template_method_example2[]
            Closure addAll = { total, item -> total += item }
            def accumulated = [1, 2, 3, 4].inject(0, addAll)
            assert accumulated == 10
            // end::template_method_example2[]

            // tag::template_method_example3[]
            accumulated = [ "1", "2", "3", "4" ].inject("", addAll)
            assert accumulated == "1234"
            // end::template_method_example3[]

            // tag::template_method_example4[]
            assert 24 == [1, 2, 3, 4].inject(1) { total, item -> total *= item }
            // end::template_method_example4[]
        '''
    }

    @Test
    void testTemplateMethod3() {
        assertScript '''
            // tag::template_method_example5[]
            assert 10 == [1, 2, 3, 4].stream().reduce(0, (l, r) -> l + r)
            assert 24 == [1, 2, 3, 4].stream().reduce(1, (l, r) -> l * r)
            assert '1234' == ['1', '2', '3', '4'].stream().reduce('', (l, r) -> l + r)
            // end::template_method_example5[]
        '''
    }

    @Test
    void testVisitorSimpleExample() {
        assertScript '''
            import groovy.transform.ToString
            // tag::visitor_simple_example[]
            abstract class Shape { }

            @ToString(includeNames=true)
            class Rectangle extends Shape {
                def x, y, w, h

                Rectangle(x, y, w, h) {
                    this.x = x; this.y = y; this.w = w; this.h = h
                }

                def union(rect) {
                    if (!rect) return this
                    def minx = [rect.x, x].min()
                    def maxx = [rect.x + rect.w, x + w].max()
                    def miny = [rect.y, y].min()
                    def maxy = [rect.y + rect.h, y + h].max()
                    new Rectangle(minx, miny, maxx - minx, maxy - miny)
                }

                def accept(visitor) {
                    visitor.visit_rectangle(this)
                }
            }

            class Line extends Shape {
                def x1, y1, x2, y2

                Line(x1, y1, x2, y2) {
                    this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2
                }

                def accept(visitor){
                    visitor.visit_line(this)
                }
            }

            class Group extends Shape {
                def shapes = []
                def add(shape) { shapes += shape }
                def remove(shape) { shapes -= shape }
                def accept(visitor) {
                    visitor.visit_group(this)
                }
            }

            class BoundingRectangleVisitor {
                def bounds

                def visit_rectangle(rectangle) {
                    if (bounds)
                        bounds = bounds.union(rectangle)
                    else
                        bounds = rectangle
                }

                def visit_line(line) {
                    def line_bounds = new Rectangle([line.x1, line.x2].min(),
                                                    [line.y1, line.y2].min(),
                                                    line.x2 - line.y1,
                                                    line.x2 - line.y2)
                    if (bounds)
                        bounds = bounds.union(line_bounds)
                    else
                        bounds = line_bounds
                }

                def visit_group(group) {
                    group.shapes.each { shape -> shape.accept(this) }
                }
            }

            def group = new Group()
            group.add(new Rectangle(100, 40, 10, 5))
            group.add(new Rectangle(100, 70, 10, 5))
            group.add(new Line(90, 30, 60, 5))
            def visitor = new BoundingRectangleVisitor()
            group.accept(visitor)
            bounding_box = visitor.bounds
            assert bounding_box.toString() == 'Rectangle(x:60, y:5, w:50, h:70)'
            // end::visitor_simple_example[]
        '''
    }

    @Test
    void testVisitorSimpleExample2() {
        assertScript '''
            import groovy.transform.ToString
            // tag::visitor_simple_example2[]
            abstract class Shape {
                def accept(Closure yield) { yield(this) }
            }

            @ToString(includeNames=true)
            class Rectangle extends Shape {
                def x, y, w, h
                def bounds() { this }
                def union(rect) {
                    if (!rect) return this
                    def minx = [ rect.x, x ].min()
                    def maxx = [ rect.x + rect.w, x + w ].max()
                    def miny = [ rect.y, y ].min()
                    def maxy = [ rect.y + rect.h, y + h ].max()
                    new Rectangle(x:minx, y:miny, w:maxx - minx, h:maxy - miny)
                }
            }

            class Line extends Shape {
                def x1, y1, x2, y2
                def bounds() {
                    new Rectangle(x:[x1, x2].min(), y:[y1, y2].min(),
                                  w:(x2 - x1).abs(), h:(y2 - y1).abs())
                }
            }

            class Group {
                def shapes = []
                def leftShift(shape) { shapes += shape }
                def accept(Closure yield) { shapes.each{it.accept(yield)} }
            }

            def group = new Group()
            group << new Rectangle(x:100, y:40, w:10, h:5)
            group << new Rectangle(x:100, y:70, w:10, h:5)
            group << new Line(x1:90, y1:30, x2:60, y2:5)
            def bounds
            group.accept{ bounds = it.bounds().union(bounds) }
            assert bounds.toString() == 'Rectangle(x:60, y:5, w:50, h:70)'
            // end::visitor_simple_example2[]
        '''
    }

    @Test
    void testVisitorSimpleExample3() {
        assertScript '''
            import groovy.transform.ToString
            import java.util.function.Function
            // tag::visitor_simple_example3[]
            abstract class Shape {
                def accept(Function<Shape, Shape> yield) { yield.apply(this) }
            }

            @ToString(includeNames=true)
            class Rectangle extends Shape {
            // end::visitor_simple_example3[]
                def x, y, w, h
                def bounds() { this }
                def union(rect) {
                    if (!rect) return this
                    def minx = [ rect.x, x ].min()
                    def maxx = [ rect.x + rect.w, x + w ].max()
                    def miny = [ rect.y, y ].min()
                    def maxy = [ rect.y + rect.h, y + h ].max()
                    new Rectangle(x:minx, y:miny, w:maxx - minx, h:maxy - miny)
                }
            // tag::visitor_simple_example3[]
                /* ... same as with Closures ... */
            }

            class Line extends Shape {
            // end::visitor_simple_example3[]
                def x1, y1, x2, y2
                def bounds() {
                    new Rectangle(x:[x1, x2].min(), y:[y1, y2].min(),
                                  w:(x2 - x1).abs(), h:(y2 - y1).abs())
                }
                /*
            // tag::visitor_simple_example3[]
                /* ... same as with Closures ... */
            }

            class Group {
                def shapes = []
                def leftShift(shape) { shapes += shape }
                def accept(Function<Shape, Shape> yield) {
                    shapes.stream().forEach(s -> s.accept(yield))
                }
            }

            def group = new Group()
            group << new Rectangle(x:100, y:40, w:10, h:5)
            group << new Rectangle(x:100, y:70, w:10, h:5)
            group << new Line(x1:90, y1:30, x2:60, y2:5)
            def bounds
            group.accept(s -> { bounds = s.bounds().union(bounds) })
            assert bounds.toString() == 'Rectangle(x:60, y:5, w:50, h:70)'
            // end::visitor_simple_example3[]
        '''
    }

    @Test
    void testVisitorAdvancedExample() {
        assertScript '''
            // tag::visitor_advanced_example[]
            interface Visitor {
                void visit(NodeType1 n1)
                void visit(NodeType2 n2)
            }

            interface Visitable {
                void accept(Visitor visitor)
            }

            class NodeType1 implements Visitable {
                Visitable[] children = new Visitable[0]
                void accept(Visitor visitor) {
                    visitor.visit(this)
                    for(int i = 0; i < children.length; ++i) {
                        children[i].accept(visitor)
                    }
                }
            }

            class NodeType2 implements Visitable {
                Visitable[] children = new Visitable[0]
                void accept(Visitor visitor) {
                    visitor.visit(this)
                    for(int i = 0; i < children.length; ++i) {
                        children[i].accept(visitor)
                    }
                }
            }

            class NodeType1Counter implements Visitor {
                int count = 0
                void visit(NodeType1 n1) {
                    count++
                }
                void visit(NodeType2 n2){}
            }
            // end::visitor_advanced_example[]

            // tag::visitor_advanced_example2[]
            NodeType1 root = new NodeType1()
            root.children = new Visitable[]{new NodeType1(), new NodeType2()}

            def counter = new NodeType1Counter()
            root.accept(counter)
            assert counter.count == 2
            // end::visitor_advanced_example2[]
        '''
    }

    @Test
    void testVisitorAdvancedExample3() {
        assertScript '''
            // tag::visitor_advanced_example3[]
            interface Visitor {
                void visit(NodeType1 n1)
                void visit(NodeType2 n2)
            }

            class DefaultVisitor implements Visitor{
                void visit(NodeType1 n1) {
                    for(int i = 0; i < n1.children.length; ++i) {
                        n1.children[i].accept(this)
                    }
                }
                void visit(NodeType2 n2) {
                    for(int i = 0; i < n2.children.length; ++i) {
                        n2.children[i].accept(this)
                    }
                }
            }

            interface Visitable {
                void accept(Visitor visitor)
            }

            class NodeType1 implements Visitable {
                Visitable[] children = new Visitable[0]
                void accept(Visitor visitor) {
                    visitor.visit(this)
                }
            }

            class NodeType2 implements Visitable {
                Visitable[] children = new Visitable[0];
                void accept(Visitor visitor) {
                    visitor.visit(this)
                }
            }

            class NodeType1Counter extends DefaultVisitor {
                int count = 0
                void visit(NodeType1 n1) {
                    count++
                    super.visit(n1)
                }
            }
            // end::visitor_advanced_example3[]
            NodeType1 root = new NodeType1()
            root.children = new Visitable[]{new NodeType1(), new NodeType2()}

            def counter = new NodeType1Counter()
            root.accept(counter)
            assert counter.count == 2
        '''
    }

    @Test
    void testVisitorAdvancedExample4() {
        assertScript '''
            // tag::visitor_advanced_example4[]
            class DefaultVisitor {
                void visit(NodeType1 n1) {
                    n1.children.each { visit(it) }
                }
                void visit(NodeType2 n2) {
                    n2.children.each { visit(it) }
                }
                void visit(Visitable v) { }
            }

            interface Visitable { }

            class NodeType1 implements Visitable {
                Visitable[] children = []
            }

            class NodeType2 implements Visitable {
                Visitable[] children = []
            }

            class NodeType1Counter extends DefaultVisitor {
                int count = 0
                void visit(NodeType1 n1) {
                    count++
                    super.visit(n1)
                }
            }
            // end::visitor_advanced_example4[]
            NodeType1 root = new NodeType1()
            root.children = new Visitable[]{new NodeType1(), new NodeType2()}

            def counter = new NodeType1Counter()
            counter.visit(root)
            assert counter.count == 2
      '''
    }

    @Test
    void testVisitorAdvancedExample5() {
        assertScript '''
            // tag::visitor_advanced_example5[]
            class DefaultVisitor {
                void visit(Visitable v) {
                    doIteration(v)
                }
                void doIteration(Visitable v) {
                    v.children.each {
                        visit(it)
                    }
                }
            }

            interface Visitable {
                Visitable[] getChildren()
            }

            class NodeType1 implements Visitable {
                Visitable[] children = []
            }

            class NodeType2 implements Visitable {
                Visitable[] children = []
            }

            class NodeType1Counter extends DefaultVisitor {
                int count = 0
                void visit(NodeType1 n1) {
                    count++
                    super.visit(n1)
                }
            }
            // end::visitor_advanced_example5[]
            NodeType1 root = new NodeType1()
            root.children = new Visitable[]{new NodeType1(), new NodeType2()}

            def counter = new NodeType1Counter()
            counter.visit(root)
            assert counter.count == 2
        '''
    }
}
