| /* |
| * Copyright 2003-2007 the original author or authors. |
| * |
| * Licensed 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 java.awt.Dimension |
| import org.codehaus.groovy.runtime.typehandling.GroovyCastException |
| |
| /** |
| * Tests the various new Groovy methods |
| * |
| * @author <a href="mailto:james@coredevelopers.net">James Strachan</a> |
| * @author Guillaume Laforge |
| * @author Dierk Koenig |
| * @author Paul King |
| * @author Joachim Baumann |
| * @version $Revision$ |
| */ |
| class GroovyMethodsTest extends GroovyTestCase { |
| void testCollect() { |
| assert [2, 4, 6].collect {it * 2} == [4, 8, 12] |
| def answer = [2, 4, 6].collect(new Vector()) {it * 2} |
| assert answer[0] == 4 |
| assert answer[1] == 8 |
| assert answer[2] == 12 |
| assert [1: 'a', 2: 'b', 3: 'c'].collect {k, v -> k + v} == ['1a', '2b', '3c'] |
| assert [1: 'a', 2: 'b', 3: 'c'].collect {it.getKey() + "*" + it.getValue()} == ['1*a', '2*b', '3*c'] |
| } |
| |
| void testAsCoercion() { |
| def d0 = new Dimension(100, 200) |
| assert d0 == new Dimension(width: 100, height: 200) |
| assert d0 == [100, 200] as Dimension |
| assert d0 == [width: 100, height: 200] as Dimension |
| } |
| |
| void testCombinations() { |
| def lists = [['a', 'b'], [1, 2, 3]] |
| assert lists.combinations() as Set == |
| [['a', 1], ['a', 2], ['a', 3], |
| ['b', 1], ['b', 2], ['b', 3]] as Set |
| } |
| |
| void testTranspose() { |
| def lists = [['a', 'b'], [1, 2, 3]] |
| assert lists.transpose() == [['a', 1], ['b', 2]] |
| } |
| |
| void testSum() { |
| assert [].sum() == null |
| assert [null].sum() == null |
| assert [1].sum() == 1 |
| assert [1, 2, 3].sum() == 6 |
| assert [1, 2, 3].sum("") == "123" |
| assert [[1, 2], [3, 4], [5, 6]].sum() == [1, 2, 3, 4, 5, 6] |
| assert [[1, 2], [3, 4], [5, 6]].sum("") == "[1, 2][3, 4][5, 6]" |
| |
| assert [].sum {it.length()} == null |
| assert [null].sum {it.toString()} == 'null' |
| assert ["abc"].sum {it.length()} == 3 |
| assert ["a", "bc", "def"].sum {it.length()} == 6 |
| assert ["a", "bc", "def"].sum("") {it.length()} == "123" |
| assert [[1, 2], [3, 4], [5, 6]].sum {it.size()} == 6 |
| assert [[1, 2], [3, 4], [5, 6]].sum {list -> list.collect {it * 2}} == [2, 4, 6, 8, 10, 12] |
| def result = [] |
| [[1, 2], [3, 4], [5, 6]].each {list -> result << list.collect {it * 2}} |
| assert result.sum() == [2, 4, 6, 8, 10, 12] |
| assert [[1, 2], [3, 4], [5, 6]].sum {list -> list.collect {it * 2}} == [2, 4, 6, 8, 10, 12] |
| } |
| |
| void testJoin() { |
| assert [2, 4, 6].join("-") == "2-4-6" |
| assert ["edam", "cheddar", "brie"].join(", ") == 'edam, cheddar, brie' |
| assert ["abc", 5, 2.34].join(", ") == "abc, 5, 2.34" |
| } |
| |
| void testTimes() { |
| def count = 0 |
| 5.times {i -> count = count + i} |
| assert count == 10 |
| count = 0 |
| def temp = 5 |
| temp.times {i -> count = count + i} |
| assert count == 10 |
| } |
| |
| void testArraySubscript() { |
| def list = [1, 2, 3, 4] |
| def array = list.toArray() |
| def value = array[2] |
| assert value == 3 |
| array[0] = 9 |
| assert array[0] == 9 |
| assert array[0..<0] == [] |
| } |
| |
| void testToCharacterMethod() { |
| def s = 'c' |
| def x = s.toCharacter() |
| assert x instanceof Character |
| } |
| |
| void testPutAtRange() { |
| def list |
| list = ['a', 'b', 'c']; list[4] = 'x'; assert list == ["a", "b", "c", null, "x"] |
| list = ['a', 'b', 'c']; list[1..2] = ['x', 'y']; assert list == ["a", "x", "y"] |
| list = ['a', 'b', 'c']; list[1..2] = 'x'; assert list == ["a", "x"] |
| list = ['a', 'b', 'c']; list[4..5] = ['x', 'y']; assert list == ["a", "b", "c", null, "x", "y"] |
| list = ['a', 'b', 'c']; list[4..5] = 'x'; assert list == ["a", "b", "c", null, "x"] |
| } |
| |
| void testGetAtRange() { |
| def list = ['a', 'b', 'c'] |
| assert list[1..2] == ['b', 'c'] |
| assert list[0..<0] == [] |
| } |
| |
| void testCharSequenceGetAt() { |
| def x = "matrix" |
| assert x[0, 5..0] == 'mxirtam' |
| assert x[3..0, 0..3] == 'rtammatr' |
| assert x[2..-4, 3..-4, 3..-3] == 'trtr' |
| assert x[-1..-3, -3..-1] == 'xirrix' |
| assert x[0..<0] == '' |
| } |
| |
| void testListGrep() { |
| def list = ["James", "Bob", "Guillaume", "Sam"] |
| def answer = list.grep(~".*a.*") |
| assert answer == ["James", "Guillaume", "Sam"] |
| answer = list.grep(~"B.b") |
| assert answer == ["Bob"] |
| } |
| |
| void testCollectionToList() { |
| def c = [1, 2, 3, 4, 5] // but it's a list |
| def l = c.toList() |
| assert l.containsAll(c) |
| assert c.size() == l.size() |
| } |
| |
| void testCollectionAsList() { |
| Integer[] nums = [1, 2, 3, 4, 5] |
| def numList = nums as List |
| nums.each {assert numList.contains(it)} |
| assert nums.size() == numList.size() |
| } |
| |
| void testCollectionAsLinkedList() { |
| Integer[] nums = [1, 2, 3, 4, 5] |
| def numList = nums as LinkedList |
| nums.each {assert numList.contains(it)} |
| assert nums.size() == numList.size() |
| assert numList.class == LinkedList.class |
| } |
| |
| void testArrayListAsLinkedList() { |
| ArrayList nums = [1, 2, 3, 4, 5] |
| shouldFail(GroovyCastException.class) { |
| def numList = nums as LinkedList |
| } |
| } |
| |
| void testFileSize() { |
| assert new File('build.properties').size() |
| } |
| |
| void testMatcherSize() { |
| assertEquals 3, ('aaa' =~ /./).count |
| assertEquals 3, ('aaa' =~ /./).size() |
| assertEquals 1, ('a' =~ /./).size() |
| assertEquals 0, ('a' =~ /x/).size() |
| } |
| |
| void testJoinString() { |
| String[] arr = ["a", "b", "c", "d"] |
| def joined = arr.join(", ") |
| assert joined == "a, b, c, d" |
| } |
| |
| void testReverseEach() { |
| def l = ["cheese", "loves", "Guillaume"] |
| def expected = ["Guillaume", "loves", "cheese"] |
| def answer = [] |
| l.reverseEach {answer << it} |
| assert answer == expected |
| } |
| |
| void testGrep() { |
| def list = ["Guillaume", "loves", "cheese"] |
| def answer = list.grep(~".*ee.*") |
| assert answer == ["cheese"] |
| list = [123, "abc", 4.56] |
| answer = list.grep(String) |
| assert answer == ["abc"] |
| list = [4, 2, 7, 3, 6, 2] |
| answer = list.grep(2..3) |
| assert answer == [2, 3, 2] |
| } |
| |
| void testMapGetWithDefault() { |
| def map = [:] |
| assert map.foo == null |
| map.get("foo", []).add(123) |
| assert map.foo == [123] |
| map.get("bar", [:]).get("xyz", [:]).cheese = 123 |
| assert map.bar.xyz.cheese == 123 |
| assert map.size() == 2 |
| } |
| |
| String getCmd() { |
| def cmd = "ls -l" |
| if (System.properties.'os.name'.contains('Win')) { |
| cmd = "cmd /c dir" |
| } |
| return cmd |
| } |
| |
| void testExecuteCommandLineProcessUsingAString() { |
| println "executing command: ${cmd}" |
| def process = cmd.execute() |
| // lets have an easier way to do this! |
| def count = 0 |
| println "Read the following lines..." |
| /** @todo we should simplify the following line!!! */ |
| new InputStreamReader(process.in).eachLine {line -> |
| println line |
| ++count |
| } |
| println "" |
| process.waitFor() |
| def value = process.exitValue() |
| println "Exit value of command line is ${value}" |
| assert count > 1 |
| } |
| |
| /* |
| void testExecuteCommandLineProcessAndUseWaitForOrKill_FAILS_ON_WINDOWS() { |
| if (System.properties.'os.name'.contains('Windows') && notYetImplemented()) return |
| |
| println "executing command: ${cmd}" |
| |
| def process = cmd.execute() |
| |
| process.consumeProcessOutput() |
| process.waitForOrKill(1000) |
| def value = process.exitValue() |
| println "Exit value of command line is ${value}" |
| |
| process = cmd.execute() |
| |
| process.consumeProcessOutput() |
| process.waitForOrKill(10) // This fails on RLW's workstation with parameter 1, >=8 is required. |
| value = process.exitValue() |
| println "Exit value of command line is ${value}" |
| |
| } |
| */ |
| |
| void testExecuteCommandLineUnderWorkingDirectory_FAILS() {if (notYetImplemented()) return |
| |
| def envp = java.util.Array.newInstance(String, 0) |
| def workDir = new File(".") |
| |
| println "executing command: ${cmd} under the directory ${workDir.canonicalPath}" |
| |
| def process = cmd.execute(envp, workDir) |
| |
| // lets have an easier way to do this! |
| def count = 0 |
| |
| println "Read the following lines under the directory ${workDir} ..." |
| |
| /** @todo we should simplify the following line!!! */ |
| new InputStreamReader(process.in).eachLine {line -> |
| println line |
| ++count |
| } |
| println "" |
| |
| process.waitFor() |
| def value = process.exitValue() |
| println "Exit value of command line is ${value}" |
| |
| assert count > 1 |
| } |
| |
| void testDisplaySystemProperties() { |
| println "System properties are..." |
| def properties = System.properties |
| def keys = properties.keySet().sort() |
| for (k in keys) { |
| println "${k} = ${properties[k]}" |
| } |
| } |
| |
| void testMax() { |
| assert [-5, -3, -1, 0, 2, 4].max {it * it} == -5 |
| } |
| |
| void testMin() { |
| assert [-5, -3, -1, 0, 2, 4].min {it * it} == 0 |
| } |
| |
| void testSort() { |
| assert [-5, -3, -1, 0, 2, 4].sort {it * it} == [0, -1, 2, -3, 4, -5] |
| } |
| |
| void testReplaceAllClosure() { |
| assert "1 a 2 b 3 c 4".replaceAll("\\p{Digit}") {it * 2} == "11 a 22 b 33 c 44" |
| } |
| |
| void testObjectSleep() { |
| long start = System.currentTimeMillis() |
| sleep 1000 |
| long slept = System.currentTimeMillis() - start |
| long epsilon = 120 |
| assert (slept > 1000 - epsilon) && (slept < 1000 + epsilon): \ |
| "should have slept for 1s (+/- " + epsilon + "ms) but was ${slept}ms" |
| } |
| |
| void testObjectSleepInterrupted() { |
| def interruptor = new groovy.TestInterruptor(Thread.currentThread()) |
| new Thread(interruptor).start() |
| long start = System.currentTimeMillis() |
| sleep 1000 |
| long slept = System.currentTimeMillis() - start |
| long epsilon = 120 |
| assert (slept > 1000 - epsilon) && (slept < 1000 + epsilon): \ |
| "should have slept for 1s (+/- " + epsilon + "ms) but was ${slept}ms" |
| } |
| |
| void testObjectSleepWithOnInterruptHandler() { |
| def log = '' |
| def interruptor = new groovy.TestInterruptor(Thread.currentThread()) |
| new Thread(interruptor).start() |
| long start = System.currentTimeMillis() |
| sleep(2000) {log += it.toString()} |
| long slept = System.currentTimeMillis() - start |
| assert slept < 2000, "should have been interrupted but slept ${slept}ms > 2s" |
| assertEquals 'java.lang.InterruptedException: sleep interrupted', log.toString() |
| } |
| |
| void testObjectSleepWithOnInterruptHandlerContinueSleeping() { |
| def log = '' |
| def interruptor = new groovy.TestInterruptor(Thread.currentThread()) |
| new Thread(interruptor).start() |
| long start = System.currentTimeMillis() |
| sleep(2000) { |
| log += it.toString() |
| false // continue sleeping |
| } |
| long slept = System.currentTimeMillis() - start |
| assert slept >= 2000, "should have continued sleeping ${slept}ms < 2s" |
| assertEquals 'java.lang.InterruptedException: sleep interrupted', log.toString() |
| } |
| |
| void testObjectIdentity() { |
| def a = new Object() |
| def b = a |
| assert a.is(b) |
| assert !a.is(null) |
| assert !1.is(2) |
| // naive impl would fall for this trap |
| assert !new WackyHashCode().is(new WackyHashCode()) |
| } |
| |
| void testGroupByList() { |
| def expected = [Integer: [1, 2], String: ["a", "b"], BigDecimal: [3.5, 4.6]] |
| def list = [1, "a", 2, "b", 3.5, 4.6] |
| def result = list.groupBy {it.class} |
| assert [1, 2] == result[Integer] |
| assert ["a", "b"] == result[String] |
| assert [3.5, 4.6] == result[BigDecimal] |
| assert 3 == result.size() |
| } |
| |
| void testGroupByMapEntry() { |
| def expectedKeys = [Integer: [1, 3], String: [2, 4], BigDecimal: [5, 6]] |
| def expectedVals = [Integer: [1, 2], String: ["a", "b"], BigDecimal: [3.5, 4.6]] |
| def map = [1: 1, 2: "a", 3: 2, 4: "b", 5: 3.5, 6: 4.6] |
| def result = map.groupBy {entry -> entry.value.class} |
| assert expectedKeys.Integer == result[Integer].collect {it.key} |
| assert expectedVals.Integer == result[Integer].collect {it.value} |
| assert expectedKeys.String == result[String].collect {it.key} |
| assert expectedVals.String == result[String].collect {it.value} |
| assert expectedKeys.BigDecimal == result[BigDecimal].collect {it.key} |
| assert expectedVals.BigDecimal == result[BigDecimal].collect {it.value} |
| assert 3 == result.size() |
| } |
| |
| def leftCol = ["2"] |
| def rightCol = ["1", "2", "3"] |
| |
| void testList() { |
| def lst = [] as LinkedList |
| doIt(lst) |
| } |
| |
| void testSetWithExplicitCoercion() { |
| def set = [] as HashSet |
| doIt(set) |
| } |
| |
| void testSetWithImplicitCoercion() { |
| Set set = [] |
| doIt(set) |
| } |
| |
| void testVector() { |
| def vctr = [] as Vector |
| doIt(vctr) |
| } |
| |
| void doIt(col) { |
| col.clear(); |
| col.addAll(leftCol); |
| // not really concerned about correctness, rather that the method can be called, however.. |
| assert col.intersect(rightCol) == ["2"] |
| } |
| } |
| |
| class WackyHashCode { |
| int hashCode() {return 1;} |
| } |