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.
@@ -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
- expectedNumber, actualNumber
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
- expectedNumber, actualNumber
35
+ expectedNumber, actualNumber
31
36
  );
32
37
  }
33
38
 
34
39
  @Ignore
35
40
  @Test
36
- public void validWhen11DigitsAndFirstIs1() {
41
+ public void cleansNumberWithMultipleSpaces() {
37
42
  final String expectedNumber = "1234567890";
38
- final String actualNumber = new PhoneNumber("11234567890").getNumber();
43
+ final String actualNumber = new PhoneNumber("123 456 7890 ").getNumber();
39
44
 
40
45
  assertEquals(
41
- expectedNumber, actualNumber
46
+ expectedNumber, actualNumber
42
47
  );
43
48
  }
44
49
 
45
50
  @Ignore
46
51
  @Test
47
- public void invalidWhenOnly11Digits() {
52
+ public void invalidWhen9Digits() {
48
53
  expectedException.expect(IllegalArgumentException.class);
49
- expectedException.expectMessage("Can only have 11 digits if number starts with '1'");
50
- new PhoneNumber("21234567890").getNumber();
54
+ expectedException.expectMessage(wrongLengthExceptionMessage);
55
+ new PhoneNumber("123456789");
51
56
  }
52
57
 
53
58
  @Ignore
54
59
  @Test
55
- public void invalidWhen9Digits() {
60
+ public void invalidWhen11Digits() {
56
61
  expectedException.expect(IllegalArgumentException.class);
57
- expectedException.expectMessage("Number must be 10 or 11 digits");
58
- new PhoneNumber("123456789").getNumber();
62
+ expectedException.expectMessage(numberIs11DigitsButDoesNotStartWith1ExceptionMessage);
63
+ new PhoneNumber("21234567890");
59
64
  }
60
65
 
61
66
  @Ignore
62
67
  @Test
63
- public void areaCode() {
64
- final String expectedAreaCode = "123";
65
- final String actualAreaCode = new PhoneNumber("1234567890").getAreaCode();
68
+ public void validWhen11DigitsAndFirstIs1() {
69
+ final String expectedNumber = "1234567890";
70
+ final String actualNumber = new PhoneNumber("11234567890").getNumber();
66
71
 
67
72
  assertEquals(
68
- expectedAreaCode, actualAreaCode
73
+ expectedNumber, actualNumber
69
74
  );
70
75
  }
71
76
 
72
77
  @Ignore
73
78
  @Test
74
- public void prettyPrint() {
75
- final String expectedPrettyNumber = "(123) 456-7890";
76
- final String actualPrettyNumber = new PhoneNumber("1234567890").pretty();
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 prettyPrintWithFullUSPhoneNumber() {
86
- final String expectedPrettyNumber = "(123) 456-7890";
87
- final String actualPrettyNumber = new PhoneNumber("11234567890").pretty();
87
+ public void invalidWithLetters() {
88
+ expectedException.expect(IllegalArgumentException.class);
89
+ expectedException.expectMessage(illegalCharacterExceptionMessage);
90
+ new PhoneNumber("123-abc-7890");
91
+ }
88
92
 
89
- assertEquals(
90
- expectedPrettyNumber, actualPrettyNumber
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
  }
@@ -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
- Placeholder
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
+
@@ -8,4 +8,4 @@ before_script:
8
8
  - bin/fetch-configlet
9
9
  script:
10
10
  - bin/configlet .
11
- - EXERCISM=1 prove -vr --exec=perl6 exercises/
11
+ - prove -re perl6 exercises/
@@ -3,15 +3,14 @@
3
3
  use Test;
4
4
  use JSON::Tiny;
5
5
 
6
- use lib ( my $dir = IO::Path.new($?FILE).parent ).path;
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 = from-json $dir.child('cases.json').slurp;
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 ( my $dir = IO::Path.new($?FILE).parent ).path;
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 = from-json $dir.child('cases.json').slurp;
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 my $path = IO::Path.new($?FILE).parent.path;
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 %tests = from-json open("$path/cases.json").slurp-rest;
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 @(%tests<valid>) {
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 @(%tests<invalid>);
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
  }