trackler 2.0.6.36 → 2.0.6.37
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/fsharp/exercises/isogram/IsogramTest.fs +70 -12
- data/tracks/fsharp/exercises/luhn/LuhnTest.fs +103 -9
- data/tracks/fsharp/exercises/nth-prime/NthPrimeTest.fs +53 -14
- data/tracks/go/config.json +5 -0
- data/tracks/go/exercises/forth/cases_test.go +246 -0
- data/tracks/go/exercises/forth/example.go +238 -0
- data/tracks/go/exercises/forth/example_gen.go +99 -0
- data/tracks/go/exercises/forth/forth_test.go +64 -0
- data/tracks/java/exercises/phone-number/src/example/java/PhoneNumber.java +19 -25
- data/tracks/java/exercises/phone-number/src/test/java/PhoneNumberTest.java +44 -30
- data/tracks/ocaml/README.md +11 -0
- data/tracks/ocaml/tools/test-generator/README.md +39 -1
- data/tracks/perl6/.travis.yml +1 -1
- data/tracks/perl6/exercises/allergies/allergies.t +118 -3
- data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +91 -3
- data/tracks/perl6/exercises/phone-number/phone-number.t +58 -5
- data/tracks/perl6/exercises/space-age/space-age.t +51 -4
- data/tracks/perl6/exercises/wordy/wordy.t +91 -4
- metadata +6 -7
- data/tracks/perl6/exercises/allergies/cases.json +0 -109
- data/tracks/perl6/exercises/atbash-cipher/cases.json +0 -82
- data/tracks/perl6/exercises/phone-number/cases.json +0 -47
- data/tracks/perl6/exercises/space-age/cases.json +0 -46
- data/tracks/perl6/exercises/wordy/cases.json +0 -89
@@ -1,11 +1,16 @@
|
|
1
|
-
import org.junit.Test;
|
2
1
|
import org.junit.Ignore;
|
3
2
|
import org.junit.Rule;
|
3
|
+
import org.junit.Test;
|
4
4
|
import org.junit.rules.ExpectedException;
|
5
5
|
|
6
|
-
import static org.junit.Assert
|
6
|
+
import static org.junit.Assert.assertEquals;
|
7
7
|
|
8
8
|
public class PhoneNumberTest {
|
9
|
+
private final static String wrongLengthExceptionMessage = "Number must be 10 or 11 digits";
|
10
|
+
private final static String numberIs11DigitsButDoesNotStartWith1ExceptionMessage =
|
11
|
+
"Can only have 11 digits if number starts with '1'";
|
12
|
+
private final static String illegalCharacterExceptionMessage =
|
13
|
+
"Illegal character in phone number. Only digits, spaces, parentheses, hyphens or dots accepted.";
|
9
14
|
|
10
15
|
@Rule
|
11
16
|
public ExpectedException expectedException = ExpectedException.none();
|
@@ -16,7 +21,7 @@ public class PhoneNumberTest {
|
|
16
21
|
final String actualNumber = new PhoneNumber("(123) 456-7890").getNumber();
|
17
22
|
|
18
23
|
assertEquals(
|
19
|
-
|
24
|
+
expectedNumber, actualNumber
|
20
25
|
);
|
21
26
|
}
|
22
27
|
|
@@ -27,68 +32,77 @@ public class PhoneNumberTest {
|
|
27
32
|
final String actualNumber = new PhoneNumber("123.456.7890").getNumber();
|
28
33
|
|
29
34
|
assertEquals(
|
30
|
-
|
35
|
+
expectedNumber, actualNumber
|
31
36
|
);
|
32
37
|
}
|
33
38
|
|
34
39
|
@Ignore
|
35
40
|
@Test
|
36
|
-
public void
|
41
|
+
public void cleansNumberWithMultipleSpaces() {
|
37
42
|
final String expectedNumber = "1234567890";
|
38
|
-
final String actualNumber = new PhoneNumber("
|
43
|
+
final String actualNumber = new PhoneNumber("123 456 7890 ").getNumber();
|
39
44
|
|
40
45
|
assertEquals(
|
41
|
-
|
46
|
+
expectedNumber, actualNumber
|
42
47
|
);
|
43
48
|
}
|
44
49
|
|
45
50
|
@Ignore
|
46
51
|
@Test
|
47
|
-
public void
|
52
|
+
public void invalidWhen9Digits() {
|
48
53
|
expectedException.expect(IllegalArgumentException.class);
|
49
|
-
expectedException.expectMessage(
|
50
|
-
new PhoneNumber("
|
54
|
+
expectedException.expectMessage(wrongLengthExceptionMessage);
|
55
|
+
new PhoneNumber("123456789");
|
51
56
|
}
|
52
57
|
|
53
58
|
@Ignore
|
54
59
|
@Test
|
55
|
-
public void
|
60
|
+
public void invalidWhen11Digits() {
|
56
61
|
expectedException.expect(IllegalArgumentException.class);
|
57
|
-
expectedException.expectMessage(
|
58
|
-
new PhoneNumber("
|
62
|
+
expectedException.expectMessage(numberIs11DigitsButDoesNotStartWith1ExceptionMessage);
|
63
|
+
new PhoneNumber("21234567890");
|
59
64
|
}
|
60
65
|
|
61
66
|
@Ignore
|
62
67
|
@Test
|
63
|
-
public void
|
64
|
-
final String
|
65
|
-
final String
|
68
|
+
public void validWhen11DigitsAndFirstIs1() {
|
69
|
+
final String expectedNumber = "1234567890";
|
70
|
+
final String actualNumber = new PhoneNumber("11234567890").getNumber();
|
66
71
|
|
67
72
|
assertEquals(
|
68
|
-
|
73
|
+
expectedNumber, actualNumber
|
69
74
|
);
|
70
75
|
}
|
71
76
|
|
72
77
|
@Ignore
|
73
78
|
@Test
|
74
|
-
public void
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
assertEquals(
|
79
|
-
expectedPrettyNumber, actualPrettyNumber
|
80
|
-
);
|
79
|
+
public void invalidWhen12Digits() {
|
80
|
+
expectedException.expect(IllegalArgumentException.class);
|
81
|
+
expectedException.expectMessage(wrongLengthExceptionMessage);
|
82
|
+
new PhoneNumber("321234567890");
|
81
83
|
}
|
82
84
|
|
83
85
|
@Ignore
|
84
86
|
@Test
|
85
|
-
public void
|
86
|
-
|
87
|
-
|
87
|
+
public void invalidWithLetters() {
|
88
|
+
expectedException.expect(IllegalArgumentException.class);
|
89
|
+
expectedException.expectMessage(illegalCharacterExceptionMessage);
|
90
|
+
new PhoneNumber("123-abc-7890");
|
91
|
+
}
|
88
92
|
|
89
|
-
|
90
|
-
|
91
|
-
|
93
|
+
@Ignore
|
94
|
+
@Test
|
95
|
+
public void invalidWithPunctuation() {
|
96
|
+
expectedException.expect(IllegalArgumentException.class);
|
97
|
+
expectedException.expectMessage(illegalCharacterExceptionMessage);
|
98
|
+
new PhoneNumber("123-@:!-7890");
|
92
99
|
}
|
93
100
|
|
101
|
+
@Ignore
|
102
|
+
@Test
|
103
|
+
public void invalidWithRightNumberOfDigitsButLettersMixedIn() {
|
104
|
+
expectedException.expect(IllegalArgumentException.class);
|
105
|
+
expectedException.expectMessage(illegalCharacterExceptionMessage);
|
106
|
+
new PhoneNumber("1a2b3c4d5e6f7g8h9i0j");
|
107
|
+
}
|
94
108
|
}
|
data/tracks/ocaml/README.md
CHANGED
@@ -47,6 +47,17 @@ In this example, the Makefile would look for an implementation in ocaml_exercise
|
|
47
47
|
|
48
48
|
All pull requests are run through a Travis CI build, which compiles and runs tests.
|
49
49
|
|
50
|
+
## Canonical test data
|
51
|
+
|
52
|
+
If you are implementing an existing test, there may be "canonical data" for it in the [x-common](https://github.com/exercism/x-common) repository.
|
53
|
+
An example: https://github.com/exercism/x-common/blob/master/exercises/bracket-push/canonical-data.json
|
54
|
+
|
55
|
+
You should base your tests off this data, in order to provide consistency across different language tracks.
|
56
|
+
|
57
|
+
There is a test generator which can create test code from these json files and an OCaml template file that you
|
58
|
+
would need to create. It is a work in progress, so may not work for every exercise. If you wish to use it, there
|
59
|
+
is documentation [here](tools/test-generator/README.md).
|
60
|
+
|
50
61
|
## Feedback
|
51
62
|
|
52
63
|
If you find this documentation is inaccurate or incomplete, or can be improved in any way, please don't hesitate to raise an [issue](https://github.com/exercism/xocaml/issues) or submit a pull request.
|
@@ -1 +1,39 @@
|
|
1
|
-
|
1
|
+
## What does it do
|
2
|
+
|
3
|
+
The test generator takes canonical-data.json files from the x-common folder, and
|
4
|
+
uses them to create Ocaml tests.
|
5
|
+
|
6
|
+
For each exercise, it requires a template file under the tools/test-generator/templates folder.
|
7
|
+
The template format is rather ad-hoc, but works for most of the exercises that have
|
8
|
+
canonical data.
|
9
|
+
|
10
|
+
## Building
|
11
|
+
|
12
|
+
In the folder tools/test-generator, type ```Make```
|
13
|
+
This will build and run the unit tests
|
14
|
+
|
15
|
+
## Running
|
16
|
+
|
17
|
+
The test generator should be run whenever test canonical data is updated.
|
18
|
+
|
19
|
+
You will need the latest version of x-common checked out locally, at the same level as your
|
20
|
+
xocaml repo.
|
21
|
+
|
22
|
+
Please note: running will overwrite tests in the xocaml/exercises folders (this is the default, there
|
23
|
+
is a command line option to write the tests to a different folder - run test_gen.native --help).
|
24
|
+
|
25
|
+
To run, type test_gen.native at the command line.
|
26
|
+
|
27
|
+
If you type git status, you will see test files that have been updated.
|
28
|
+
|
29
|
+
Some files can be generated but will look better after hand-editing. An example is the minesweeper exercise,
|
30
|
+
where a list that is part of the input is better presented in a 2D vertically aligned format. To handle this,
|
31
|
+
the test generator saves it's files in a folder in your home (~/.xocaml-generated - this can be overridden as
|
32
|
+
a command line option). If after generation, the file is unchanged from the saved copy, then the test generator
|
33
|
+
will not overwrite the test in the repo - so git status will be clean.
|
34
|
+
|
35
|
+
## Extending
|
36
|
+
|
37
|
+
If you find an exercise that the generator cannot handle, pull requests to extend it are welcome.
|
38
|
+
|
39
|
+
|
data/tracks/perl6/.travis.yml
CHANGED
@@ -3,15 +3,14 @@
|
|
3
3
|
use Test;
|
4
4
|
use JSON::Tiny;
|
5
5
|
|
6
|
-
use lib
|
6
|
+
use lib $?FILE.IO.dirname;
|
7
7
|
|
8
8
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Allergies';
|
9
9
|
require ::($module) <&allergic-to &list-allergies>;
|
10
10
|
|
11
11
|
plan 2;
|
12
12
|
|
13
|
-
my %cases
|
14
|
-
|
13
|
+
my %cases;
|
15
14
|
subtest 'allergic-to' => {
|
16
15
|
my @cases = |%cases{'allergic_to'}{'cases'};
|
17
16
|
|
@@ -38,3 +37,119 @@ subtest 'list' => {
|
|
38
37
|
or diag $_;
|
39
38
|
}
|
40
39
|
};
|
40
|
+
|
41
|
+
done-testing;
|
42
|
+
|
43
|
+
INIT {
|
44
|
+
%cases := from-json 「
|
45
|
+
{
|
46
|
+
"allergic_to": {
|
47
|
+
"description": [
|
48
|
+
"Given a number and a substance, indicate whether Tom is allergic ",
|
49
|
+
"to that substance.",
|
50
|
+
"Test cases for this method involve more than one assertion.",
|
51
|
+
"Each case in 'expected' specifies what the method should return for",
|
52
|
+
"the given substance."
|
53
|
+
],
|
54
|
+
"cases": [
|
55
|
+
{
|
56
|
+
"description": "no allergies means not allergic",
|
57
|
+
"score": 0,
|
58
|
+
"expected": [
|
59
|
+
{
|
60
|
+
"substance": "peanuts",
|
61
|
+
"result": false
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"substance": "cats",
|
65
|
+
"result": false
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"substance": "strawberries",
|
69
|
+
"result": false
|
70
|
+
}
|
71
|
+
]
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"description": "is allergic to eggs",
|
75
|
+
"score": 1,
|
76
|
+
"expected": [
|
77
|
+
{
|
78
|
+
"substance": "eggs",
|
79
|
+
"result": true
|
80
|
+
}
|
81
|
+
]
|
82
|
+
},
|
83
|
+
{
|
84
|
+
"description": "allergic to eggs in addition to other stuff",
|
85
|
+
"score": 5,
|
86
|
+
"expected": [
|
87
|
+
{
|
88
|
+
"substance": "eggs",
|
89
|
+
"result": true
|
90
|
+
},
|
91
|
+
{
|
92
|
+
"substance": "shellfish",
|
93
|
+
"result": true
|
94
|
+
},
|
95
|
+
{
|
96
|
+
"substance": "strawberries",
|
97
|
+
"result": false
|
98
|
+
}
|
99
|
+
]
|
100
|
+
}
|
101
|
+
]
|
102
|
+
},
|
103
|
+
"list": {
|
104
|
+
"description": ["Given a number, list all things Tom is allergic to"],
|
105
|
+
"cases": [
|
106
|
+
{
|
107
|
+
"description": "no allergies at all",
|
108
|
+
"score": 0,
|
109
|
+
"expected": []
|
110
|
+
},
|
111
|
+
{
|
112
|
+
"description": "allergic to just eggs",
|
113
|
+
"score": 1,
|
114
|
+
"expected": ["eggs"]
|
115
|
+
},
|
116
|
+
{
|
117
|
+
"description": "allergic to just peanuts",
|
118
|
+
"score": 2,
|
119
|
+
"expected": ["peanuts"]
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"description": "allergic to just strawberries",
|
123
|
+
"score": 8,
|
124
|
+
"expected": ["strawberries"]
|
125
|
+
},
|
126
|
+
{
|
127
|
+
"description": "allergic to eggs and peanuts",
|
128
|
+
"score": 3,
|
129
|
+
"expected": ["eggs", "peanuts"]
|
130
|
+
},
|
131
|
+
{
|
132
|
+
"description": "allergic to more than eggs but not peanuts",
|
133
|
+
"score": 5,
|
134
|
+
"expected": ["eggs", "shellfish"]
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"description": "allergic to lots of stuff",
|
138
|
+
"score": 248,
|
139
|
+
"expected": ["strawberries", "tomatoes", "chocolate", "pollen", "cats"]
|
140
|
+
},
|
141
|
+
{
|
142
|
+
"description": "allergic to everything",
|
143
|
+
"score": 255,
|
144
|
+
"expected": ["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"description": "ignore non allergen score parts",
|
148
|
+
"score": 509,
|
149
|
+
"expected": ["eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]
|
150
|
+
}
|
151
|
+
]
|
152
|
+
}
|
153
|
+
}
|
154
|
+
」
|
155
|
+
}
|
@@ -3,15 +3,14 @@
|
|
3
3
|
use Test;
|
4
4
|
use JSON::Tiny;
|
5
5
|
|
6
|
-
use lib
|
6
|
+
use lib $?FILE.IO.dirname;
|
7
7
|
|
8
8
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Cipher';
|
9
9
|
require ::($module) <&encode &decode>;
|
10
10
|
|
11
11
|
plan 2;
|
12
12
|
|
13
|
-
my %cases
|
14
|
-
|
13
|
+
my %cases;
|
15
14
|
subtest 'encode' => {
|
16
15
|
my @cases = |%cases.<encode>.<cases>;
|
17
16
|
|
@@ -29,3 +28,92 @@ subtest 'decode' => {
|
|
29
28
|
is decode( .<phrase> ), .<expected>, .<description>
|
30
29
|
for @cases;
|
31
30
|
};
|
31
|
+
|
32
|
+
done-testing;
|
33
|
+
|
34
|
+
INIT {
|
35
|
+
%cases := from-json 「
|
36
|
+
{
|
37
|
+
"#": [
|
38
|
+
"The tests are divided into two groups: ",
|
39
|
+
"* Encoding from English to atbash cipher",
|
40
|
+
"* Decoding from atbash cipher to all-lowercase-mashed-together English"
|
41
|
+
],
|
42
|
+
"encode": {
|
43
|
+
"description": ["Test encoding from English to atbash"],
|
44
|
+
"cases": [
|
45
|
+
{
|
46
|
+
"description": "encode yes",
|
47
|
+
"phrase": "yes",
|
48
|
+
"expected": "bvh"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"description": "encode no",
|
52
|
+
"phrase": "no",
|
53
|
+
"expected": "ml"
|
54
|
+
},
|
55
|
+
{
|
56
|
+
"description": "encode OMG",
|
57
|
+
"phrase": "OMG",
|
58
|
+
"expected": "lnt"
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"description": "encode spaces",
|
62
|
+
"phrase": "O M G",
|
63
|
+
"expected": "lnt"
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"description": "encode mindblowingly",
|
67
|
+
"phrase": "mindblowingly",
|
68
|
+
"expected": "nrmwy oldrm tob"
|
69
|
+
},
|
70
|
+
{
|
71
|
+
"description": "encode numbers",
|
72
|
+
"phrase": "Testing,1 2 3, testing.",
|
73
|
+
"expected": "gvhgr mt123 gvhgr mt"
|
74
|
+
},
|
75
|
+
{
|
76
|
+
"description": "encode deep thought",
|
77
|
+
"phrase": "Truth is fiction.",
|
78
|
+
"expected": "gifgs rhurx grlm"
|
79
|
+
},
|
80
|
+
{
|
81
|
+
"description": "encode all the letters",
|
82
|
+
"phrase": "The quick brown fox jumps over the lazy dog.",
|
83
|
+
"expected": "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"description": "encode ignores non ascii",
|
87
|
+
"phrase": "non ascii éignored",
|
88
|
+
"expected": "mlmzh xrrrt mlivw"
|
89
|
+
}
|
90
|
+
]
|
91
|
+
},
|
92
|
+
"decode": {
|
93
|
+
"description": ["Test decoding from atbash to English"],
|
94
|
+
"cases": [
|
95
|
+
{
|
96
|
+
"description": "decode exercism",
|
97
|
+
"phrase": "vcvix rhn",
|
98
|
+
"expected": "exercism"
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"description": "decode a sentence",
|
102
|
+
"phrase": "zmlyh gzxov rhlug vmzhg vkkrm thglm v",
|
103
|
+
"expected": "anobstacleisoftenasteppingstone"
|
104
|
+
},
|
105
|
+
{
|
106
|
+
"description": "decode numbers",
|
107
|
+
"phrase": "gvhgr mt123 gvhgr mt",
|
108
|
+
"expected": "testing123testing"
|
109
|
+
},
|
110
|
+
{
|
111
|
+
"description": "decode all the letters",
|
112
|
+
"phrase": "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt",
|
113
|
+
"expected": "thequickbrownfoxjumpsoverthelazydog"
|
114
|
+
}
|
115
|
+
]
|
116
|
+
}
|
117
|
+
}
|
118
|
+
」
|
119
|
+
}
|
@@ -2,15 +2,14 @@
|
|
2
2
|
use v6;
|
3
3
|
use Test;
|
4
4
|
use JSON::Tiny;
|
5
|
-
use lib
|
5
|
+
use lib $?FILE.IO.dirname;
|
6
6
|
|
7
7
|
plan 12;
|
8
8
|
my $module = %*ENV<EXERCISM> ?? 'Example' !! 'Phone';
|
9
9
|
use-ok $module;
|
10
10
|
require ::($module) <Phone>;
|
11
11
|
|
12
|
-
my %
|
13
|
-
|
12
|
+
my %cases;
|
14
13
|
subtest 'number, area-code and pretty methods', {
|
15
14
|
plan 3;
|
16
15
|
ok Phone.can('number'), 'can Phone.number';
|
@@ -18,7 +17,7 @@ subtest 'number, area-code and pretty methods', {
|
|
18
17
|
ok Phone.can('pretty'), 'can Phone.pretty';
|
19
18
|
} or fail 'Missing method(s).';
|
20
19
|
|
21
|
-
for @(%
|
20
|
+
for @(%cases<valid>) {
|
22
21
|
my $phone = Phone.new(number => .<input>);
|
23
22
|
my $msg = 'for ' ~ .<test>;
|
24
23
|
is $phone.number, .<number>, "number $msg";
|
@@ -29,5 +28,59 @@ for @(%tests<valid>) {
|
|
29
28
|
todo 'Optional Exception Tests' unless %*ENV<EXERCISM>; # Remove this line for invalid input tests
|
30
29
|
subtest 'Throw exceptions for invalid input', {
|
31
30
|
plan 5;
|
32
|
-
throws-like {Phone.new(number => .<input>)}, Exception, .<test> for @(%
|
31
|
+
throws-like {Phone.new(number => .<input>)}, Exception, .<test> for @(%cases<invalid>);
|
32
|
+
}
|
33
|
+
|
34
|
+
done-testing;
|
35
|
+
|
36
|
+
INIT {
|
37
|
+
%cases := from-json 「
|
38
|
+
{
|
39
|
+
"valid": [
|
40
|
+
{
|
41
|
+
"input": 1234567890,
|
42
|
+
"number": "1234567890",
|
43
|
+
"area-code": "123",
|
44
|
+
"pretty": "(123) 456-7890",
|
45
|
+
"test": "10 digit integer"
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"input": "+1 (234) 555-6789",
|
49
|
+
"number": "2345556789",
|
50
|
+
"area-code": "234",
|
51
|
+
"pretty": "(234) 555-6789",
|
52
|
+
"test": "11 digit formatted number"
|
53
|
+
},
|
54
|
+
{
|
55
|
+
"input": "1.379.555.2468",
|
56
|
+
"number": "3795552468",
|
57
|
+
"area-code": "379",
|
58
|
+
"pretty": "(379) 555-2468",
|
59
|
+
"test": "11 digit number containing separators"
|
60
|
+
}
|
61
|
+
],
|
62
|
+
"invalid": [
|
63
|
+
{
|
64
|
+
"input": "",
|
65
|
+
"test": "empty input"
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"input": "13579",
|
69
|
+
"test": "5 digit number"
|
70
|
+
},
|
71
|
+
{
|
72
|
+
"input": "123456789011",
|
73
|
+
"test": "12 digit number"
|
74
|
+
},
|
75
|
+
{
|
76
|
+
"input": "+2 (468) 555-1379",
|
77
|
+
"test": "11 digit number not beginning with 1"
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"input": "phone number",
|
81
|
+
"test": "not a number"
|
82
|
+
}
|
83
|
+
]
|
84
|
+
}
|
85
|
+
」
|
33
86
|
}
|