Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrofit Groovy language track tests as Spock specifications #31

Merged
merged 11 commits into from
Nov 28, 2016
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.swp
*.beam
.project
.DS_Store
tmp
bin/configlet
Expand Down
60 changes: 6 additions & 54 deletions SETUP.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,12 @@
These instructions assume you have installed exercism, Groovy, Java, and have an available IDE (this guide uses IntelliJ IDEA). If you run into trouble, consult the exercism docs on [Groovy](http://exercism.io/languages/groovy), or send us an issue on GitHub.
For installation and learning resources, refer to the
[exercism help page](http://exercism.io/languages/groovy).

## Fetch the exercise

In a Command Prompt or Terminal, fetch the first exercise.
Run the tests by executing the test script.

```
C:\Users\You>exercism fetch groovy

Not Submitted: 1 problem
groovy (Hello World) Path\To\Your\Exercism\groovy\hello-world

New: 1 problem
groovy (Hello World) Path\To\Your\Exercism\groovy\hello-world

unchanged: 0, updated: 0, new: 1
$ groovy ./HelloWorldSpec.groovy
```

## Import the exercise

1) Start IntelliJ IDEA. In the "Welcome to IntelliJ IDEA" window, click the "Open" option.

2) Navigate to the "Path\To\Your\Exercism\groovy\THIS_EXERCISE" folder. Make sure you've selected the root directory of the exercise. Click "OK".

3) Follow the dialog for creating the project from existing external sources.

4) IntelliJ will then create a new project structure in the editor for your exercise.

5) Depending on how much of the IDE you have configured before, you will likely need to add a Groovy SDK and a Java SDK (JDK 7+, ideally). These can be configured through the project/module settings by right clicking on the imported project.

6) You may also need to configure the location of the compiler output (exercism doesn't provide all IDE files since you could work the problems in a myriad of editors instead). This can be configured in the project settings as well.

## Start the exercise

1) Open the `README.md` file and carefully read the background for the assignment.

2) Start by running the test suite: In the "Project" view, right-click on the test file (`hello-world\HelloWorldTest.groovy`), select "Run", then pick the "HelloWorldTest" that has a JUnit icon to the left of it (red and green arrows).

3) The tests are designed to fail at the beginning. Each exercise will expect you to update the associated groovy file (named the same as the test without the ````Tests```` suffix in the filename.

4) To skip a test, you can add the @Ignore annotation a test method:

````
//This test will run.
@Test
void testNoName() {
assertTrue new HelloWorld().hello() == 'Hello, World!'
}

//this test will be skipped.
@Test
@Ignore
void testSampleName() {
assertTrue new HelloWorld().hello('Alice') == 'Hello, Alice!'
}
````

Alternatively, you can simply comment out an entire method to have it removed from compilation and being included in test output.
After the first test(s) pass, continue by commenting out or removing the `@Ingore` annotations prepending other tests.

5) Update the main Groovy code and re-run the tests until they pass.
When all tests pass, congratulations!
32 changes: 17 additions & 15 deletions exercises/difference-of-squares/Example.groovy
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
class Squares {
def naturalNum

def Squares(num) {
this.naturalNum = num
}
def naturalNum

def squareOfSums() {
(1..naturalNum).inject(0) {result, i -> result += i } ** 2
}
def Squares(num) {
this.naturalNum = num
}

def sumOfSquares() {
(1..naturalNum).inject(0) {result, i ->
result += i ** 2
}
}
def squareOfSums() {
(1..naturalNum).inject(0) {result, i -> result += i } ** 2
}

def sumOfSquares() {
(1..naturalNum).inject(0) {result, i ->
result += i ** 2
}
}

def difference() {
squareOfSums() - sumOfSquares()
}

def difference() {
squareOfSums() - sumOfSquares()
}
}
30 changes: 30 additions & 0 deletions exercises/difference-of-squares/SquaresSpec.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@Grab('org.spockframework:spock-core:1.0-groovy-2.4')
import spock.lang.*

class SquaresSpec extends Specification {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These test are a good chance to show off Spock's parameterised tests with something like this for each one:

@Unroll
def 'can square the sum of the numbers up to the given number: #num'() {
    expect:
        new Squares(num).squareOfSums() == expected

    where:
        num   || expected
        5     || 225
        10    || 3025
        100   || 25502500
}


def 'can square the sum of the numbers up to the given number'() {
expect:
new Squares(5).squareOfSums() == 225
new Squares(10).squareOfSums() == 3025
new Squares(100).squareOfSums() == 25502500
}

@Ignore
def 'can sum the squares of the numbers up to the given number'() {
expect:
new Squares(5).sumOfSquares() == 55
new Squares(10).sumOfSquares() == 385
new Squares(100).sumOfSquares() == 338350
}

@Ignore
def 'can subtract sum of squares from square of sums'() {
expect:
new Squares(0).difference() == 0
new Squares(5).difference() == 170
new Squares(10).difference() == 2640
new Squares(100).difference() == 25164150
}

}
49 changes: 0 additions & 49 deletions exercises/difference-of-squares/SquaresTest.groovy

This file was deleted.

16 changes: 9 additions & 7 deletions exercises/gigasecond/Example.groovy
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
class Example {
def from(Date dateObject) {
def seconds = dateObject.getTime() / 1000
def gs = seconds + 10**9
new Date((long) gs * 1000)
}
}
import groovy.time.TimeCategory

class Gigasecond {

static Date from(Date date) {
use ( TimeCategory ) { date + (10**9).seconds }
}

}
7 changes: 5 additions & 2 deletions exercises/gigasecond/Gigasecond.groovy
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
class Gigasecond {
//TODO define your function here.
}

// YOUR CODE HERE
// HINT: methods that don't change the state of an object can be 'static'

}
38 changes: 38 additions & 0 deletions exercises/gigasecond/GigasecondSpec.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@Grab('org.spockframework:spock-core:1.0-groovy-2.4')
import spock.lang.*
import static java.util.Calendar.*

class GigasecondSpec extends Specification {

def gigasecond = new Gigasecond()

def 'calculates one gigasecond after a date'() {
given:
def start = Date.parse('yyyy-MMM-dd', '2011-Apr-25')
when:
def result = gigasecond.from(start)
then:
result == Date.parse('yyyy-MMM-dd hh:mm:ss', '2043-Jan-01 00:46:40')
}

@Ignore
def 'calculates one gigasecond after a date with hours and minutes'() {
given:
def start = Date.parse('yyyy-MMM-dd hh:mm', '1959-Jul-19 12:31')
when:
def result = gigasecond.from(start)
then:
result == Date.parse('yyyy-MMM-dd hh:mm:ss', '1991-Mar-27 01:17:40')
}

@Ignore
def 'calculates one gigasecond after a date with hours and minutes and seconds'() {
given:
def start = Date.parse('yyyy-MMM-dd hh:mm:ss', '1977-Jun-13 02:15:45')
when:
def result = gigasecond.from(start)
then:
result == Date.parse('yyyy-MMM-dd hh:mm:ss', '2009-Feb-19 03:02:25')
}

}
29 changes: 0 additions & 29 deletions exercises/gigasecond/GigasecondTest.groovy

This file was deleted.

12 changes: 7 additions & 5 deletions exercises/hamming/Example.groovy
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
class Hamming {
def compute(strand1, strand2) {
(0..[strand1.size(), strand2.size()].min() - 1).step(1).count() {
strand1[it] != strand2[it]
}
}

def compute(strand1, strand2) {
(0..[strand1.size(), strand2.size()].min() - 1).step(1).count() {
strand1[it] != strand2[it]
}
}

}
50 changes: 50 additions & 0 deletions exercises/hamming/HammingSpec.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@Grab('org.spockframework:spock-core:1.0-groovy-2.4')
import spock.lang.*

class HammingSpec extends Specification {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it's mentioned somewhere else (in the exercise?), but if I only look at this spec I wouldn't know (the overview of) what a Hamming-distance is and what the letters stand for

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An exercise is assembled from various sources. For example, the description for The Hamming exercise can be found at x-common/exercises/hamming


def 'computes zero distance for identical strands'() {
expect: new Hamming().compute('A','A') == 0
}

@Ignore
def 'computes the distance for a single nucleotide strand'() {
expect: new Hamming().compute('A','G') == 1
}

@Ignore
def 'computes the distance for a small strand'() {
expect: new Hamming().compute('AG','CT') == 2
}

@Ignore
def 'computes a small Hamming distance'() {
expect: new Hamming().compute('AT','CT') == 1
}

@Ignore
def 'computes a small Hamming distance in a longer strand'() {
expect: new Hamming().compute('GGACG','GGTCG') == 1
}

@Ignore
def 'ignores additional nucleotides when the first strand is longer'() {
expect: new Hamming().compute('AGAGACTTA','AAA') == 1
}

@Ignore
def 'ignores additional nucleotides when the second strand is longer'() {
expect: new Hamming().compute('AGG','AAAACTGACCCACCCCAGG') == 2
}

@Ignore
def 'computes a large Hamming distance'() {
expect: new Hamming().compute('GATACA','GCATAA') == 4
}

@Ignore
def 'computes a very long Hamming distance'() {
expect: new Hamming().compute('GGACGGATTCTG','AGGACGGATTCT') == 9
}

}
Loading