| /* |
| * 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. |
| */ |
| package groovy |
| |
| import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM |
| |
| /** |
| * Tests the various Closure methods in Groovy |
| * |
| * @author <a href="mailto:james@coredevelopers.net">James Strachan</a> |
| */ |
| class ClosureMethodTest extends GroovyTestCase { |
| |
| void testListCollect() { |
| def list = [1, 2, 3, 4] |
| def answer = list.collect{item -> return item * 2 } |
| assert answer.size() == 4 |
| def expected = [2, 4, 6, 8] |
| assert answer == expected |
| } |
| |
| void testMapCollect() { |
| def map = [1:2, 2:4, 3:6, 4:8] |
| def answer = map.collect{e-> return e.key + e.value } |
| // lest sort the results since maps are in hash code order |
| answer = answer.sort() |
| assert answer.size() == 4 |
| assert answer == [3, 6, 9, 12] |
| assert answer.get(0) == 3 |
| assert answer.get(1) == 6 |
| assert answer.get(2) == 9 |
| assert answer.get(3) == 12 |
| } |
| |
| void testObjectFindResult() { |
| def oneToTenObjectIterator = { |
| def i = 1 |
| [ hasNext: { i <= 10 }, next: { i++ } ] as Iterator |
| } |
| |
| assert "Found 3" == oneToTenObjectIterator().findResult { |
| if (it > 2) return "Found $it" |
| } |
| |
| assert false == oneToTenObjectIterator().findResult { |
| if (it > 2) return false |
| } |
| |
| assert null == oneToTenObjectIterator().findResult { |
| if (false) return "won't get here, should return null" |
| } |
| |
| assert "Found 3" == oneToTenObjectIterator().findResult("default") { |
| if (it > 2) return "Found $it" |
| } |
| |
| assert "default" == oneToTenObjectIterator().findResult("default") { |
| if (false) return "won't get here, should return null" |
| } |
| } |
| |
| void testListFind() { |
| def list = ["a", "b", "c"] |
| def answer = list.find{item-> item == "b" } |
| assert answer == "b" |
| answer = list.find{item-> item == "z" } |
| assert answer == null |
| } |
| |
| void testListFindResult() { |
| Collection<Integer> oneThroughFive = [1, 2, 3, 4, 5] |
| |
| assert "I found 4" == oneThroughFive.findResult { |
| if (it > 3) return "I found $it" |
| } |
| |
| assert null == oneThroughFive.findResult { |
| if (it > 8) return "I found $it" |
| } |
| |
| assert null == [].findResult { |
| if (it) return "I found $it" |
| } |
| |
| assert false == oneThroughFive.findResult { |
| if (it > 3) return false // a result of false is a valid result |
| } |
| |
| assert "I found 3" == oneThroughFive.findResult("default") { |
| if (it > 2) return "I found $it" |
| } |
| |
| assert "default" == oneThroughFive.findResult("default") { |
| if (it > 8) return "I found $it" |
| } |
| } |
| |
| void testMapFind() { |
| def map = [1:2, 2:4, 3:6, 4:8] |
| def answer = map.find{entry -> entry.value == 6 } |
| assert answer != null |
| assert answer.key == 3 |
| assert answer.value == 6 |
| answer = map.find{entry -> entry.value == 0 } |
| assert answer == null |
| answer = map.find{ k, v -> v > 5 } |
| assert answer instanceof Map.Entry |
| assert answer.key == 3 |
| assert answer.value == 6 |
| |
| answer = map.find{ k, v -> k == 2 } |
| assert answer instanceof Map.Entry |
| assert answer.key == 2 |
| assert answer.value == 4 |
| } |
| |
| void testMapFindResult() { |
| def oneThroughFourMap = [a: 1, b: 2, c: 3, d: 4] |
| |
| assert "I found c:3" == oneThroughFourMap.findResult { entry -> |
| if (entry.value > 2) return "I found ${entry.key}:${entry.value}" |
| } |
| |
| assert "I found c:3" == oneThroughFourMap.findResult { key, value -> |
| if (value > 2) return "I found ${key}:${value}" |
| } |
| |
| assert false == oneThroughFourMap.findResult { |
| if (it.value > 2) return false // a result of false is a valid result |
| } |
| |
| assert "I found c:3" == oneThroughFourMap.findResult("default") { key, value -> |
| if (value > 2) return "I found ${key}:${value}" |
| } |
| |
| assert "default" == oneThroughFourMap.findResult("default") { key, value -> |
| if (value > 10) return "I found ${key}:${value}" |
| } |
| } |
| |
| void testListFindAll() { |
| def list = [20, 5, 40, 2] |
| def answer = list.findAll{item -> item < 10 } |
| assert answer.size() == 2 |
| assert answer == [5, 2] |
| } |
| |
| void testMapFindAll() { |
| def map = [1:2, 2:4, 3:6, 4:8] |
| def answer = map.findAll{ entry -> entry.value > 5 } |
| assert answer.size() == 2 |
| def keys = answer.collect { entry -> entry.key } |
| def values = answer.collect { entry -> entry.value } |
| // maps are in hash order so lets sort the results |
| keys.sort() |
| values.sort() |
| assert keys == [3, 4], "Expected [3, 4] but was $keys" |
| assert values == [6, 8], "Expected [6, 8] but was $values" |
| } |
| |
| void testMapEach() { |
| def count = 0 |
| def map = [1:2, 2:4, 3:6, 4:8] |
| map.each{e-> count = count + e.value } |
| assert count == 20 |
| map.each{e-> count = count + e.value + e.key } |
| assert count == 50 |
| } |
| |
| void testMapEachWith2Params() { |
| def count = 0 |
| def map = [1:2, 2:4, 3:6, 4:8] |
| map.each {key, value -> count = count + value } |
| assert count == 20 |
| map.each {key, value -> count = count + value + key } |
| assert count == 50 |
| } |
| |
| void testListEach() { |
| def count = 0 |
| def list = [1, 2, 3, 4] |
| list.each({item-> count = count + item }) |
| assert count == 10 |
| list.each{item-> count = count + item } |
| assert count == 20 |
| } |
| |
| void testListEvery() { |
| assert [1, 2, 3, 4].every {i-> return i < 5 } |
| assert [1, 2, 7, 4].every {i-> i < 5 } == false |
| assert [a:1, b:2, c:3].every {k,v -> k < 'd' && v < 4 } |
| assert ![a:1, b:2, c:3].every {k,v -> k < 'd' && v < 3 } |
| } |
| |
| void testListAny() { |
| assert [1, 2, 3, 4].any {i-> return i < 5 } |
| assert [1, 2, 3, 4].any {i-> i > 3 } |
| assert [1, 2, 3, 4].any {i-> i > 5 } == false |
| assert [a:1, b:2, c:3].any { k,v -> k == 'c' } |
| def isThereAFourValue = [a:1, b:2, c:3].any{ k,v -> v == 4 } |
| assert !isThereAFourValue |
| } |
| |
| void testJoin() { |
| def value = [1, 2, 3].join('-') |
| assert value == "1-2-3" |
| } |
| |
| void testListReverse() { |
| def value = [1, 2, 3, 4].reverse() |
| assert value == [4, 3, 2, 1] |
| } |
| |
| void testListInject() { |
| def value = [1, 2, 3].inject('counting: ') { str, item -> str + item } |
| assert value == "counting: 123" |
| value = [1, 2, 3].inject(0) { c, item -> c + item } |
| assert value == 6 |
| value = ([1, 2, 3, 4] as Object[]).inject(0) { c, item -> c + item } |
| assert value == 10 |
| } |
| |
| void testOneArgListInject() { |
| // Check basic functionality |
| def value = [ 1, 2, 3 ].inject { c, item -> c + item } |
| assert value == 6 |
| |
| // Check a use-case |
| value = [ [ 'tim', 'dave', 'chris' ], |
| [ 'stuart', 'harry', 'tim' ], |
| [ 'bert', 'tim', 'ernie' ] ] |
| assert value.inject { a, b -> a.intersect( b ) } == ['tim'] |
| |
| // Check edges |
| try { |
| [].inject { a, b -> a + b } == null |
| fail( "inject(Closure) on an emtpy list should throw a NoSuchElementException" ) |
| } |
| catch ( NoSuchElementException e ) { |
| } |
| assert [ 1 ].inject { a, b -> a + b } == 1 |
| assert [ 1, 2 ].inject { a, b -> a + b } == 3 |
| } |
| |
| void testOneArgObjectInject() { |
| def value = ([1, 2, 3, 4] as Object[]).inject { c, item -> c + item } |
| assert value == 10 |
| |
| try { |
| ([] as Object[]).inject { c, item -> c + item } |
| fail( "inject(Closure) on an emtpy Object[] should throw a NoSuchElementException" ) |
| } |
| catch ( NoSuchElementException e ) { |
| } |
| |
| value = ([ 1 ] as Object[]).inject { c, item -> c + item } |
| assert value == 1 |
| |
| def i = 1 |
| def iter = [ hasNext:{ -> i < 5 }, next:{ -> i++ } ] as Iterator |
| assert iter.inject { a, b -> a * b } == 24 |
| |
| try { |
| iter = [ hasNext:{ -> false }, next:{ -> null } ] as Iterator |
| iter.inject { a, b -> a * b } |
| fail( "inject(Closure) on an exhaused iterator should throw a NoSuchElementException" ) |
| } |
| catch ( NoSuchElementException e ) { |
| } |
| |
| i = 1 |
| iter = [ hasNext:{ -> i <= 1 }, next:{ -> i++ } ] as Iterator |
| assert iter.inject { a, b -> a * b } == 1 |
| } |
| |
| void testOldAndNewStylesYieldSameResults() { |
| def items = [1000, 200, 30, 4] |
| def twice = { int x -> x * 2 } |
| def checkEqual = { int a, b -> assert a == b; a } |
| def sum = DGM.&sum |
| def addThreeWays = [ |
| items.sum(), |
| items.inject(0, sum), |
| items.inject(sum) |
| ] |
| assert addThreeWays == [1234] * 3 |
| addThreeWays.inject(checkEqual) |
| |
| def addTwiceFourWays = [ |
| items.inject(0){ int acc, next -> acc + twice(next) }, |
| items.collect(twice).sum(), |
| items.collect(twice).inject(0, sum), |
| items.collect(twice).inject(sum) |
| ] |
| assert addTwiceFourWays == [2468] * 4 |
| addTwiceFourWays.inject(checkEqual) |
| } |
| |
| void testObjectInject() { |
| def value = [1:1, 2:2, 3:3].inject('counting: ') { str, item -> str + item.value } |
| assert value == "counting: 123" |
| value = [1:1, 2:2, 3:3].inject(0) { c, item -> c + item.value } |
| assert value == 6 |
| } |
| |
| void testIteratorInject() { |
| def value = [1:1, 2:2, 3:3].iterator().inject('counting: ') { str, item -> str + item.value } |
| assert value == "counting: 123" |
| value = [1:1, 2:2, 3:3].iterator().inject(0) { c, item -> c + item.value } |
| assert value == 6 |
| } |
| |
| void testDump() { |
| def text = dump() |
| assert text != null && text.startsWith("<") |
| } |
| |
| void testInspect() { |
| def text = [1, 2, 'three'].inspect() |
| assert text == "[1, 2, 'three']" |
| } |
| |
| void testTokenize() { |
| def text = "hello-there-how-are-you" |
| def answer = [] |
| for (i in text.tokenize('-')) { |
| answer.add(i) |
| } |
| assert answer == ['hello', 'there', 'how', 'are', 'you'] |
| } |
| |
| void testUpto() { |
| def answer = [] |
| 1.upto(5) { answer.add(it) } |
| assert answer == [1, 2, 3, 4, 5] |
| } |
| } |