blob: 4ba4625adb4ed42427599ba2b3ca957154a709b8 [file] [log] [blame]
import groovy.test.GroovyTestCase
/*
* 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.
*/
class CommandChainsTest extends GroovyTestCase {
void testCommandChainEquivalence() {
assertScript '''String left = 'left'
String right = 'right'
class Move {
def list = []
Move turn(direction) {
list << direction
this
}
Move then(direction) {
list << direction
this
}
}
def m1 = new Move()
def m2 = new Move()
m1.with {
// tag::commandchain_1[]
// equivalent to: turn(left).then(right)
turn left then right
// end::commandchain_1[]
}
m2.turn(left).then(right)
assert m1.list == ['left', 'right']
assert m1.list == m2.list
'''
assertScript '''import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
class DSL {
int qt
String medicine
int duration
def take(qty) {
qt = qty
this
}
def of(med) {
medicine = med
this
}
def after(dur) {
duration = dur
this
}
}
class IntCategory {
public static int getPills(Integer x) {
x
}
public static int getHours(Integer x) {
x
}
}
String chloroquinine = 'chloroquinine'
def m1 = new DSL()
def m2 = new DSL()
use(IntCategory) {
m1.with {
// tag::commandchain_2[]
// equivalent to: take(2.pills).of(chloroquinine).after(6.hours)
take 2.pills of chloroquinine after 6.hours
// end::commandchain_2[]
}
m2.take(2.pills).of(chloroquinine).after(6.hours)
}
assert m1.qt == 2
assert m1.medicine == 'chloroquinine'
assert m1.duration == 6
assert m1 == m2
'''
assertScript '''import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
class DSL {
String object
List<String> colors = []
def paint(obj) {
object = obj
this
}
def with(String... c) {
colors.addAll(c as List)
this
}
def and(String... c) {
colors.addAll(c as List)
this
}
}
String wall = 'wall'
String red = 'red'
String green = 'green'
String yellow = 'yellow'
def m1 = new DSL()
def m2 = new DSL()
m1.with {
// tag::commandchain_3[]
// equivalent to: paint(wall).with(red, green).and(yellow)
paint wall with red, green and yellow
// end::commandchain_3[]
}
m2.paint(wall).with(red, green).and(yellow)
assert m1 == m2
assert m1.object == 'wall'
assert m1.colors == ['red','green','yellow']
'''
assertScript '''import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
class DSL {
def map = [:]
boolean test
def check(m) { map=m; this}
def tastes(taste) {
test = taste=='good'?map.that=='margarita':false
}
}
def margarita = 'margarita'
def good = 'good'
def m1 = new DSL()
def m2 = new DSL()
m1.with {
// tag::commandchain_4[]
// with named parameters too
// equivalent to: check(that: margarita).tastes(good)
check that: margarita tastes good
// end::commandchain_4[]
}
m2.check(that: margarita).tastes(good)
assert m1 == m2
assert m1.map == [that: 'margarita']
assert m1.test == true
'''
assertScript '''
class DSL {
int count
void cpt(Closure c) { count++ }
def given(Closure c) { cpt(c) ; this }
def when(Closure c) { cpt(c) ; this }
def then(Closure c) { cpt(c) ; this }
}
def m1 = new DSL()
def m2 = new DSL()
m1.with {
// tag::commandchain_5[]
// with closures as parameters
// equivalent to: given({}).when({}).then({})
given { } when { } then { }
// end::commandchain_5[]
}
m2.given({}).when({}).then({})
assert m1.count == 3
assert m2.count == 3
'''
assertScript '''import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
class DSL {
String columns
List names
boolean unique = false
def select(columns) { this.columns = columns; this }
def unique() {
unique = true;
this
}
def from(values) {
names = unique?values.unique():values
}
}
def all = 'all'
def names = ['Bob','Alice','Alice']
def m1 = new DSL()
def m2 = new DSL()
m1.with {
// tag::commandchain_6[]
// equivalent to: select(all).unique().from(names)
select all unique() from names
// end::commandchain_6[]
}
m2.select(all).unique().from(names)
assert m1 == m2
assert (m1.names as Set) == ['Bob','Alice'] as Set
'''
assertScript '''import groovy.transform.Canonical
@Canonical
class DSL {
String thing
int qte
def take(n) {
qte = n
this
}
def propertyMissing(String name) {
thing = name
}
def methodMissing(String name, args) {
if (name.startsWith('get') && !args) {
thing = name.substring(3).toLowerCase()
}
}
}
def m1 = new DSL()
def m2 = new DSL()
def m3 = new DSL()
m1.with {
// tag::commandchain_7[]
// equivalent to: take(3).cookies
// and also this: take(3).getCookies()
take 3 cookies
// end::commandchain_7[]
}
m2.take(3).cookies
m3.take(3).getCookies()
assert m1 == m2
assert m2 == m3
assert m1.qte == 3
assert m1.thing == 'cookies'
'''
}
void testCommandChainImplementation() {
assertScript '''
// tag::commandchain_impl1[]
show = { println it }
square_root = { Math.sqrt(it) }
def please(action) {
[the: { what ->
[of: { n -> action(what(n)) }]
}]
}
// equivalent to: please(show).the(square_root).of(100)
please show the square_root of 100
// ==> 10.0
// end::commandchain_impl1[]
'''
assertScript '''
// tag::commandchain_impl2[]
@Grab('com.google.guava:guava:r09')
import com.google.common.base.*
// end::commandchain_impl2[]
// tag::commandchain_impl2_assert[]
def result = Splitter.on(',').trimResults(CharMatcher.is('_' as char)).split("_a ,_b_ ,c__").iterator().toList()
// end::commandchain_impl2_assert[]
assert result == ['a ', 'b_ ', 'c']
'''
assertScript '''
// tag::commandchain_impl3[]
@Grab('com.google.guava:guava:r09')
import com.google.common.base.*
def split(string) {
[on: { sep ->
[trimming: { trimChar ->
Splitter.on(sep).trimResults(CharMatcher.is(trimChar as char)).split(string).iterator().toList()
}]
}]
}
// end::commandchain_impl3[]
// tag::commandchain_impl3_assert[]
def result = split "_a ,_b_ ,c__" on ',' trimming '_\'
// end::commandchain_impl3_assert[]
'''
}
}