Appendix D. Cheat sheets

Cheat sheets provide you with quick information and examples to get you up and running quickly. For more details about any topic, refer to the corresponding section in the book or on the Groovy web site’s wiki.

Lists

See section 4.2.

assert [1,2,3,4]       == (1..4)
assert [1,2,3] + [1]   == [1,2,3,1]
assert [1,2,3] << 1    == [1,2,3,1]
assert [1,2,3,1] - [1] == [2,3]
assert [1,2,3] * 2     == [1,2,3,1,2,3]
assert [1,[2,3]].flatten() == [1,2,3]
assert [1,2,3].reverse()   == [3,2,1]
assert [1,2,3].disjoint([4,5,6])
assert [1,2,3].intersect([4,3,1]) == [3,1]
assert [1,2,3].collect{ it+3 }    == [4,5,6]
assert [1,2,3,1].unique().size()  == 3
assert [1,2,3,1].count(1) == 2
assert [1,2,3,4].min()    == 1
assert [1,2,3,4].max()    == 4
assert [1,2,3,4].sum()    == 10
assert [4,2,1,3].sort()   == [1,2,3,4]
assert [4,2,1,3].findAll{ it%2 == 0 } == [4,2]
def animals = ['cat','kangaroo','koala','dog']
assert animals[2] == 'koala'
def kanimals = animals[1..2]
assert animals.findAll{ it =~ /k.*/ } == kanimals
assert animals.find{ it =~ /k.*/ }    == kanimals[0]
assert animals.grep(~/k.*/)           == kanimals

Closures

See chapter 5.

def add  = { x, y -> x + y }
def mult = { x, y -> x * y }
assert add(1,3)  == 4
assert mult(1,3) == 3
def min = { x, y -> [x,y].min() }
def max = { x, y -> [x,y].max() }
def atLeastTen = max.curry(10)
assert atLeastTen(5)  == 10
assert atLeastTen(15) == 15
def pairWise(list, Closure invoke) {
    if (list.size() < 2) return []
    def next = invoke(list[0],list[1])
    return [next] + pairWise(list[1..-1], invoke)
    }
    assert pairWise(1..5, add)  == [3, 5, 7, 9]
    assert pairWise(1..5, mult) == [2, 6, 12, 20]
    assert pairWise(1..5, min)  == [1, 2, 3, 4]
    assert pairWise(1..5, max)  == [2, 3, 4, 5]
    assert 'cbaxabc' == ['a','b','c'].inject('x'){
            result, item -> item + result + item }
    assert [1,2,3].grep{ it<3 } == [1,2]
    assert [1,2,3].any{ it%2 == 0 }
    assert [1,2,3].every{ it<4 }
    assert (1..9).collect{it}.join()   == '123456789'
    assert (1..4).collect{it*2}.join() == '2468'

Regular expressions

See section 3.5.

Table D.1. Regular expressions

Symbol

Meaning

.

Any character

^

Start of line (or start of document, when in single-line mode)

$

End of line (or end of document, when in single-line mode)

d

Digit character

D

Any character except digits

s

Whitespace character

S

Any character except whitespace

w

Word character

W

Any character except word characters



Word boundary

()

Grouping

(x|y)

x or y as in (Groovy|Java|Ruby)

1

Backmatch to group one; for example, find doubled characters with (.)1

x*

Zero or more occurrences of x

x+

One or more occurrences of x

x?

Zero or one occurrence of x

x{m,n}

At least m and at most n occurrences of x

x{m}

Exactly m occurrences of x

[a-f]

Character class containing the characters a, b, c, d, e, f

[^a]

Character class containing any character except a

[aeiou]

Character class representing lowercase vowels

[a-z&&[^aeiou]]

Lowercase consonants

[a0zA-Z0-9]

Uppercase or lowercase letter or digit

[+|-]?(d+(.d*)?)|(.d+)

Positive or negative floating-point number

^[w-.]+@([w-]+.)+[w-]{2,4}$

Simple email validation

(?is:x)

Switches mode when evaluating x; i turns on ignoreCase, s is single-line mode

(?=regex)

Positive lookahead

(?<=text)

Positive lookbehind

Examples:

def twister = 'she sells sea shells by the sea shore'
// contains word 'shore'
assert twister =~ 'shore'
// contains 'sea' twice (two ways)
assert (twister =~ 'sea').count == 2
assert twister.split(/ /).grep(~/sea/).size() == 2
// words that start with 'sh',  = word boundary
def shwords = (twister =~ /sh[a-z]*/).collect{it}.join(' ')
assert shwords == 'she shells shore'
// four words have three letter, S = non-Space letter
assert (twister =~ /S{3}/).count == 4
// three words start with 's' and have 5 or 6 letters
assert (twister =~ /sS{4}S?/).count == 3
// replace words with 'X', w = word character
assert twister.replaceAll(/w+/,'X') == 'X X X X X X X X'
// starts with 'she' and ends with 'shore'
def pattern = ~/she.*shore/
assert pattern.matcher(twister).matches()
// replace 'sea' with 'ocean' but only if preceded by word 'the'
def ocean = twister.replaceAll('(?<=the )sea','ocean')
assert ocean == 'she sells sea shells by the ocean shore'
// swap 1st and 2nd pairs of words
def pairs = twister =~ /(S+) (S+) ?/
assert pairs.hasGroup()
twister = [1, 0, 2, 3].collect{ pairs[it][0] }.join()
assert twister = 'sea shells she sells by the sea shore'

Unit testing

See chapter 14.

Groovy tests may be written in scripts or in classes that extend GroovyTestCase, both of which can use the normal groovy command or a test runner within your IDE or build environment. One useful method provided by GroovyTestCase is shouldFail, which lets you easily test failure conditions. You can also use asserts within your test scripts.

Mocks and stubs

See section 14.5.2.

Use stubs when you want to replace an object with one that accepts all the calls of an original object. This is typically done when you want to perform state-based testing. Use mocks when you want to apply stricter expectations on your objects in order to do interaction-based testing.

As an example, suppose you want to test the following class with sufficient tests to reach 100 percent coverage, and either method1 or method2 could throw an exception:

class MyClass {
    def method() {
        try {
            new Collaborator1().method1()
            new Collaborator2().method2()
        } catch (Exception e) {
            new Collaborator3().method3()
        }
    }
}

Here is one way you could write your test code:

import groovy.mock.interceptor.MockFor
class MyClassTest extends GroovyTestCase {
    def mock1 = new MockFor(Collaborator1)
    def mock2 = new MockFor(Collaborator2)
    def mock3 = new MockFor(Collaborator3)
    private static final Closure PASS = {}
    private static final Closure FAIL = {
        throw new RuntimeException()
    }
    void testSuccess() {
        check(PASS, PASS, null)
    }
    void testCollaborator1Fails() {
        check(FAIL, null, PASS)
    }
    void testCollaborator2Fails() {
        check(PASS, FAIL, PASS)
    }
    private check(expected1, expected2, expected3){
        if (expected1) mock1.demand.method1(expected1)
        if (expected2) mock2.demand.method2(expected2)
        if (expected3) mock3.demand.method3(expected3)
        mock1.use { mock2.use { mock3.use {
            new MyClass().method()
        }}}
   }
}

XML GPath notation

See chapter 12.

Groovy supports special notation for common XML processing activities. Consider the following XML:

def recipeXml = '''
<recipe>
   <ingredients>
      <ingredient amount='2 cups'>Self-raising Flour</ingredient>
      <ingredient amount='2 tablespoons'>Icing sugar</ingredient>
      <ingredient amount='2 tablespoons'>Butter</ingredient>
      <ingredient amount='3/4 - 1 cup'>Milk</ingredient>
   </ingredients>
   <steps>
      <step>Preheat oven to 230 degrees celsius</step>
      <step>Sift flour and icing sugar into a bowl</step>
      <step>Melt butter and mix into dry ingredients</step>
      <step>Gradually add milk to the mixture until moist</step>
      <step>Turn onto floured board and cut into portions</step>
      <step>Bake for 15 minutes</step>
      <step>Serve with jam and whipped cream</step>
   </steps>
</recipe>
'''

Using XmlSlurper, XmlParser, or DOMCategory, you can write the following notation to process this XML:

assert 4 == recipe.ingredients.ingredient.size()
// should be 14 elements in total
assert 14 == recipe.'**'.findAll{true}.size()
// step 4 (index 3 because we start from 0) involves milk
assert recipe.steps.step[3].text().contains('milk')
assert '2 cups' == recipe.ingredients.ingredient[0].'@amount'.toString()
// two ingredients have '2 tablespoons' amount attribute
def ingredients = recipe.ingredients.ingredient.grep{
    it.'@amount' == '2 tablespoons'
}
assert ingredients.size() == 2
// every step has at least 4 words
assert recipe.steps.step.every{
    step -> step.text().tokenize(' ').size() >= 4
}

Initialization for XmlSlurper looks like this:

def recipe  = new XmlSlurper().parseText(recipeXml)
/* ... processing steps ... */

Initialization for XmlParser looks like this:

def recipe  = new XmlParser().parseText(recipeXml)
/* ... processing steps ... */

Initialization for DOMCategory looks like this:

def reader  = new StringReader(recipeXml)
def doc     = groovy.xml.DOMBuilder.parse(reader)
def recipe  = doc.documentElement
use (groovy.xml.dom.DOMCategory) {
    /* ... processing steps ... */
}

 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.39.60