# Triangle Groovy Koan

Thought I’d post a “Groovy Koan.”

The following is a Groovy version of a solution to the Triangle Ruby Koan, which (in part) challenges the student to code the following problem:

```# Triangle analyzes the lengths of the sides of a triangle
# (represented by a, b and c) and returns the type of triangle.
#
# It returns:
#   :equilateral  if all sides are equal
#   :isosceles    if exactly 2 sides are equal
#   :scalene      if no sides are equal
#
def triangle(a, b, c)
# WRITE THIS CODE
end
```

What you’ll see here arguably represents a ‘sexier’ solution than many others out there.

It’s not all my own work: its an amalgam of the various versions that were discussed during the workshop that I talked about earlier. So thanks to my fellow participants.

Here goes nothin’…

First, the solution:

```// file: triangle/Triangle.groovy
package triangle

class Triangle {
static triangle(_a, _b, _c) {
def coll = [_a, _b, _c]
def (a, b, c) = coll.sort()
if ((a + b) <= c)
throw new TriangleException()
TriangleType.values()[coll.unique().size() - 1]
}
}

// NB: order is important here
enum TriangleType {
EQUILATERAL, ISOSCELES, SCALENE
}

class TriangleException extends Exception {}
```

Rather than follow the Ruby Koan testing path I have decided to find my own way and use the very neat Spock testing framework. Viz:

```// file: TriangleSpec.groovy
import spock.lang.*
import triangle.*

public class TriangleSpec extends spock.lang.Specification {

@Unroll("#iterationCount: <#a, #b, #c> represents an EQUILATERAL triangle.")
def "test equilateral triangles have equal sides"(a, b, c) {
expect:
TriangleType.EQUILATERAL == Triangle.triangle(a, b, c)
where:
a |  b |  c
2 |  2 |  2
10 | 10 | 10
}

@Unroll("#iterationCount: <#a, #b, #c> represents an ISOSCELES triangle.")
def "test isosceles triangles have exactly two sides equal"(a, b, c) {
expect:
TriangleType.ISOSCELES == Triangle.triangle(a, b, c)
where:
a |  b |  c
3 |  4 |  4
4 |  3 |  4
4 |  4 |  3
10 | 10 |  2
}

@Unroll("#iterationCount: <#a, #b, #c> represents a SCALENE triangle.")
def "test scalene triangles have no equal sides"(a, b, c) {
expect:
TriangleType.SCALENE == Triangle.triangle(a, b, c)
where:
a |  b |  c
3 |  4 |  5
10 | 11 | 12
5 |  4 |  2
}

@Unroll("#iterationCount: <#a, #b, #c> represents an illegal triangle.")
def "test illegal triangles throw exceptions"(a, b, c) {
when:
Triangle.triangle(a, b, c)
then:
thrown(TriangleException)
where:
a | b |  c
0 | 0 |  0
3 | 4 | -5
1 | 1 |  3
2 | 4 |  2
}
}
```

Does it work? Yes. Yes it does: And in (a somewhat round-about) homage to Jim Wierich (author of Ruby’s equivalent ‘rake‘ tool), I have used Gradle for build automation and dependency management:

```// file: build.gradle
apply plugin: "groovy"

repositories {
mavenCentral()
}

dependencies {
groovy("org.codehaus.groovy:groovy-all:2.0.5")
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}

// ALWAYS do tests regardless of up-to-date checking
test.outputs.upToDateWhen { false }
```