trackler 2.0.0.1 → 2.0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bump-content +3 -1
  3. data/bin/verify-metadata +2 -2
  4. data/common/exercises/alphametics/canonical-data.json +19 -9
  5. data/common/exercises/food-chain/canonical-data.json +7 -1
  6. data/common/exercises/grains/canonical-data.json +66 -0
  7. data/common/exercises/raindrops/description.md +4 -5
  8. data/common/exercises/triangle/canonical-data.json +81 -54
  9. data/lib/trackler/version.rb +1 -1
  10. data/tracks/c/config.json +26 -19
  11. data/tracks/c/exercises/allergies/makefile +15 -0
  12. data/tracks/c/exercises/allergies/src/allergies.h +21 -0
  13. data/tracks/c/exercises/allergies/src/example.c +32 -0
  14. data/tracks/c/exercises/allergies/src/example.h +26 -0
  15. data/tracks/c/exercises/allergies/test/test_allergies.c +203 -0
  16. data/tracks/c/exercises/allergies/test/vendor/unity.c +1300 -0
  17. data/tracks/c/exercises/allergies/test/vendor/unity.h +274 -0
  18. data/tracks/c/exercises/allergies/test/vendor/unity_internals.h +701 -0
  19. data/tracks/c/exercises/atbash-cipher/makefile +16 -0
  20. data/tracks/c/exercises/atbash-cipher/src/example.c +71 -0
  21. data/tracks/c/exercises/atbash-cipher/src/example.h +7 -0
  22. data/tracks/c/exercises/atbash-cipher/test/test_atbash_cipher.c +113 -0
  23. data/tracks/c/exercises/atbash-cipher/test/vendor/unity.c +1300 -0
  24. data/tracks/c/exercises/atbash-cipher/test/vendor/unity.h +274 -0
  25. data/tracks/c/exercises/atbash-cipher/test/vendor/unity_internals.h +701 -0
  26. data/tracks/c/exercises/phone-number/makefile +16 -0
  27. data/tracks/c/exercises/phone-number/src/example.c +66 -0
  28. data/tracks/c/exercises/phone-number/src/example.h +8 -0
  29. data/tracks/c/exercises/phone-number/test/test_phone_number.c +108 -0
  30. data/tracks/c/exercises/phone-number/test/vendor/unity.c +1300 -0
  31. data/tracks/c/exercises/phone-number/test/vendor/unity.h +274 -0
  32. data/tracks/c/exercises/phone-number/test/vendor/unity_internals.h +701 -0
  33. data/tracks/csharp/config.json +8 -0
  34. data/tracks/csharp/exercises/bowling/BowlingTest.cs +188 -33
  35. data/tracks/csharp/exercises/bowling/Example.cs +38 -9
  36. data/tracks/csharp/exercises/rectangles/Example.cs +91 -0
  37. data/tracks/csharp/exercises/rectangles/RectanglesTest.cs +133 -0
  38. data/tracks/elisp/docs/INSTALLATION.org +1 -1
  39. data/tracks/elixir/config.json +8 -66
  40. data/tracks/elixir/docs/LEARNING.md +1 -1
  41. data/tracks/elixir/exercises/diamond/diamond_test.exs +12 -12
  42. data/tracks/elixir/exercises/grep/example.exs +92 -0
  43. data/tracks/elixir/exercises/grep/grep.exs +6 -0
  44. data/tracks/elixir/exercises/grep/grep_test.exs +259 -0
  45. data/tracks/elixir/exercises/markdown/markdown.exs +59 -2
  46. data/tracks/elixir/exercises/nucleotide-count/nucleotide_count_test.exs +4 -4
  47. data/tracks/elixir/exercises/phone-number/phone_number_test.exs +5 -0
  48. data/tracks/fsharp/exercises/bowling/BowlingTest.fs +158 -43
  49. data/tracks/fsharp/exercises/bowling/Example.fs +53 -24
  50. data/tracks/go/config.json +5 -0
  51. data/tracks/go/exercises/diamond/diamond_test.go +227 -0
  52. data/tracks/go/exercises/diamond/example.go +47 -0
  53. data/tracks/go/exercises/food-chain/example.go +1 -1
  54. data/tracks/go/exercises/food-chain/food_chain_test.go +30 -6
  55. data/tracks/go/exercises/nucleotide-count/example.go +21 -8
  56. data/tracks/go/exercises/nucleotide-count/nucleotide_count_test.go +45 -37
  57. data/tracks/haskell/exercises/anagram/test/Tests.hs +1 -11
  58. data/tracks/java/bin/journey-test.sh +165 -128
  59. data/tracks/java/docs/ABOUT.md +5 -8
  60. data/tracks/java/exercises/hello-world/build.gradle +0 -6
  61. data/tracks/java/exercises/hello-world/src/test/java/HelloWorldTest.java +0 -1
  62. data/tracks/java/exercises/meetup/build.gradle +0 -1
  63. data/tracks/java/exercises/meetup/src/example/java/Meetup.java +9 -7
  64. data/tracks/java/exercises/meetup/src/test/java/MeetupTest.java +185 -188
  65. data/tracks/lua/config.json +0 -73
  66. data/tracks/lua/exercises/bowling/bowling_spec.lua +92 -48
  67. data/tracks/lua/exercises/bowling/example.lua +4 -1
  68. data/tracks/objective-c/config.json +9 -30
  69. data/tracks/objective-c/exercises/pangram/PangramExample.h +7 -0
  70. data/tracks/objective-c/exercises/pangram/PangramExample.m +21 -0
  71. data/tracks/objective-c/exercises/pangram/PangramTest.m +51 -0
  72. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
  73. data/tracks/ocaml/README.md +46 -1
  74. data/tracks/ocaml/SETUP.md +21 -2
  75. data/tracks/ocaml/config.json +48 -78
  76. data/tracks/perl5/README.md +15 -8
  77. data/tracks/perl5/testall.pl +5 -5
  78. data/tracks/php/config.json +26 -34
  79. data/tracks/php/docs/ABOUT.md +15 -0
  80. data/tracks/php/exercises/allergies/allergies_test.php +121 -0
  81. data/tracks/php/exercises/allergies/example.php +64 -0
  82. data/tracks/php/exercises/etl/etl_test.php +52 -0
  83. data/tracks/php/exercises/etl/example.php +12 -0
  84. data/tracks/php/exercises/nucleotide-count/example.php +25 -0
  85. data/tracks/php/exercises/nucleotide-count/nucleotide-count_test.php +36 -0
  86. data/tracks/php/exercises/pig-latin/example.php +25 -29
  87. data/tracks/php/exercises/pig-latin/pig-latin_test.php +26 -19
  88. data/tracks/php/exercises/space-age/example.php +65 -0
  89. data/tracks/php/exercises/space-age/space-age_test.php +70 -0
  90. data/tracks/php/exercises/triangle/example.php +43 -0
  91. data/tracks/php/exercises/triangle/triangle_test.php +140 -0
  92. data/tracks/pony/exercises/anagram/example.pony +6 -6
  93. data/tracks/pony/exercises/anagram/test.pony +3 -4
  94. data/tracks/pony/exercises/bob/test.pony +23 -23
  95. data/tracks/pony/exercises/difference-of-squares/test.pony +11 -11
  96. data/tracks/pony/exercises/hamming/example.pony +3 -3
  97. data/tracks/pony/exercises/hamming/test.pony +16 -16
  98. data/tracks/pony/exercises/hello-world/test.pony +5 -4
  99. data/tracks/pony/exercises/leap/test.pony +8 -8
  100. data/tracks/python/config.json +18 -0
  101. data/tracks/python/exercises/diamond/diamond_test.py +33 -0
  102. data/tracks/python/exercises/diamond/example.py +15 -0
  103. data/tracks/python/exercises/linked-list/example.py +47 -0
  104. data/tracks/python/exercises/linked-list/linked_list.py +13 -0
  105. data/tracks/python/exercises/linked-list/linked_list_test.py +49 -0
  106. data/tracks/python/exercises/list-ops/example.py +55 -0
  107. data/tracks/python/exercises/list-ops/list_ops.py +38 -0
  108. data/tracks/python/exercises/list-ops/list_ops_test.py +136 -0
  109. data/tracks/ruby/bin/generate +22 -2
  110. data/tracks/ruby/config.json +12 -83
  111. data/tracks/ruby/exercises/allergies/allergies_test.rb +0 -1
  112. data/tracks/ruby/exercises/atbash-cipher/atbash_cipher_test.rb +0 -1
  113. data/tracks/ruby/exercises/beer-song/beer_song_test.rb +1 -2
  114. data/tracks/ruby/exercises/binary/example.rb +0 -1
  115. data/tracks/ruby/exercises/binary-search-tree/binary_search_tree_test.rb +1 -1
  116. data/tracks/ruby/exercises/bowling/.version +1 -0
  117. data/tracks/ruby/exercises/bowling/bowling_test.rb +109 -133
  118. data/tracks/ruby/exercises/bowling/example.rb +7 -7
  119. data/tracks/ruby/exercises/bowling/example.tt +27 -0
  120. data/tracks/ruby/exercises/circular-buffer/circular_buffer_test.rb +0 -2
  121. data/tracks/ruby/exercises/clock/example.rb +0 -2
  122. data/tracks/ruby/exercises/connect/connect_test.rb +0 -1
  123. data/tracks/ruby/exercises/custom-set/custom_set_test.rb +0 -1
  124. data/tracks/ruby/exercises/diamond/diamond_test.rb +0 -1
  125. data/tracks/ruby/exercises/etl/etl_test.rb +1 -1
  126. data/tracks/ruby/exercises/house/house_test.rb +0 -1
  127. data/tracks/ruby/exercises/isogram/isogram_test.rb +2 -2
  128. data/tracks/ruby/exercises/largest-series-product/example.tt +0 -3
  129. data/tracks/ruby/exercises/largest-series-product/largest_series_product_test.rb +0 -4
  130. data/tracks/ruby/exercises/linked-list/linked_list_test.rb +1 -1
  131. data/tracks/ruby/exercises/meetup/meetup_test.rb +0 -1
  132. data/tracks/ruby/exercises/nth-prime/example.tt +0 -2
  133. data/tracks/ruby/exercises/nth-prime/nth_prime_test.rb +0 -2
  134. data/tracks/ruby/exercises/ocr-numbers/ocr_numbers_test.rb +1 -2
  135. data/tracks/ruby/exercises/protein-translation/protein_translation_test.rb +0 -1
  136. data/tracks/ruby/exercises/proverb/proverb_test.rb +1 -3
  137. data/tracks/ruby/exercises/queen-attack/example.rb +3 -1
  138. data/tracks/ruby/exercises/queen-attack/queen_attack_test.rb +34 -8
  139. data/tracks/ruby/exercises/robot-simulator/robot_simulator_test.rb +1 -1
  140. data/tracks/ruby/exercises/strain/strain_test.rb +2 -2
  141. data/tracks/ruby/exercises/tournament/.version +1 -0
  142. data/tracks/ruby/exercises/tournament/example.rb +54 -0
  143. data/tracks/ruby/exercises/tournament/example.tt +23 -0
  144. data/tracks/ruby/exercises/tournament/tournament_test.rb +92 -0
  145. data/tracks/ruby/exercises/transpose/.version +1 -0
  146. data/tracks/ruby/exercises/transpose/example.rb +14 -0
  147. data/tracks/ruby/exercises/transpose/example.tt +22 -0
  148. data/tracks/ruby/exercises/transpose/transpose_test.rb +303 -0
  149. data/tracks/ruby/lib/bowling_cases.rb +46 -0
  150. data/tracks/ruby/lib/isogram_cases.rb +1 -1
  151. data/tracks/ruby/lib/tournament_cases.rb +45 -0
  152. data/tracks/ruby/lib/transpose_cases.rb +45 -0
  153. data/tracks/rust/config.json +2 -0
  154. data/tracks/rust/exercises/bowling/.gitignore +7 -0
  155. data/tracks/rust/exercises/bowling/Cargo.toml +3 -0
  156. data/tracks/rust/exercises/bowling/example.rs +134 -0
  157. data/tracks/rust/exercises/bowling/tests/bowling.rs +373 -0
  158. data/tracks/rust/exercises/grains/.gitignore +7 -0
  159. data/tracks/rust/exercises/grains/Cargo.toml +3 -0
  160. data/tracks/rust/exercises/grains/example.rs +11 -0
  161. data/tracks/rust/exercises/grains/src/lib.rs +7 -0
  162. data/tracks/rust/exercises/grains/tests/grains.rs +63 -0
  163. data/tracks/rust/problems.md +2 -0
  164. data/tracks/scala/README.md +38 -0
  165. data/tracks/scala/config.json +20 -74
  166. data/tracks/scala/exercises/accumulate/src/test/scala/accumulate_test.scala +4 -0
  167. data/tracks/scala/exercises/allergies/src/test/scala/allergies_test.scala +11 -0
  168. data/tracks/scala/exercises/alphametics/build.sbt +6 -0
  169. data/tracks/scala/exercises/alphametics/example.scala +125 -0
  170. data/tracks/scala/exercises/alphametics/src/main/scala/.keep +0 -0
  171. data/tracks/scala/exercises/alphametics/src/test/scala/AlphameticsTest.scala +62 -0
  172. data/tracks/scala/exercises/atbash-cipher/src/test/scala/atbash_test.scala +8 -0
  173. data/tracks/scala/exercises/bank-account/src/test/scala/BankAccountTest.scala +4 -0
  174. data/tracks/scala/exercises/binary/src/test/scala/binary_test.scala +13 -0
  175. data/tracks/scala/exercises/binary-search-tree/src/test/scala/BstTest.scala +11 -0
  176. data/tracks/scala/exercises/bowling/Example.scala +116 -0
  177. data/tracks/scala/exercises/bowling/build.sbt +3 -0
  178. data/tracks/scala/exercises/bowling/src/main/scala/Bowling.scala +11 -0
  179. data/tracks/scala/exercises/bowling/src/test/scala/BowlingSuite.scala +237 -0
  180. data/tracks/scala/exercises/clock/src/test/scala/ClockTest.scala +50 -0
  181. data/tracks/scala/exercises/connect/README.md +17 -0
  182. data/tracks/scala/exercises/connect/src/test/scala/ConnectTest.scala +7 -0
  183. data/tracks/scala/exercises/crypto-square/src/test/scala/{CrytpoSquareTest.scala → CryptoSquareTest.scala} +9 -0
  184. data/tracks/scala/exercises/custom-set/src/test/scala/CustomSetTest.scala +36 -0
  185. data/tracks/scala/exercises/difference-of-squares/src/test/scala/squares_test.scala +8 -0
  186. data/tracks/scala/exercises/forth/src/test/scala/ForthTest.scala +22 -0
  187. data/tracks/scala/exercises/hexadecimal/src/test/scala/HexadecimalTest.scala +8 -0
  188. data/tracks/scala/exercises/kindergarten-garden/src/test/scala/GardenTest.scala +5 -0
  189. data/tracks/scala/exercises/largest-series-product/src/test/scala/SeriesTest.scala +2 -0
  190. data/tracks/scala/exercises/linked-list/src/test/scala/DequeTest.scala +4 -0
  191. data/tracks/scala/exercises/luhn/src/test/scala/LuhnTest.scala +4 -0
  192. data/tracks/scala/exercises/matrix/src/test/scala/MatrixTest.scala +2 -0
  193. data/tracks/scala/exercises/minesweeper/src/test/scala/MinesweeperTest.scala +6 -0
  194. data/tracks/scala/exercises/nth-prime/src/test/scala/PrimeTest.scala +5 -0
  195. data/tracks/scala/exercises/ocr-numbers/src/test/scala/OcrTest.scala +15 -0
  196. data/tracks/scala/exercises/octal/src/test/scala/OctalTest.scala +7 -0
  197. data/tracks/scala/exercises/parallel-letter-frequency/src/test/scala/FrequencyTest.scala +8 -0
  198. data/tracks/scala/exercises/pascals-triangle/src/test/scala/PascalsTriangleTest.scala +5 -0
  199. data/tracks/scala/exercises/pig-latin/src/test/scala/PigLatinTest.scala +4 -0
  200. data/tracks/scala/exercises/pythagorean-triplet/src/test/scala/PythagoreanTripletTest.scala +3 -0
  201. data/tracks/scala/exercises/queen-attack/src/test/scala/QueensTest.scala +5 -0
  202. data/tracks/scala/exercises/robot-simulator/src/test/scala/RobotTest.scala +16 -8
  203. data/tracks/scala/exercises/say/src/test/scala/SayTest.scala +34 -17
  204. data/tracks/scala/exercises/scrabble-score/src/test/scala/scrabble_score_test.scala +6 -0
  205. data/tracks/scala/exercises/secret-handshake/src/test/scala/SecretHandshakeTest.scala +18 -9
  206. data/tracks/scala/exercises/series/src/test/scala/SeriesTest.scala +4 -2
  207. data/tracks/scala/exercises/sieve/src/test/scala/SieveTest.scala +8 -4
  208. data/tracks/scala/exercises/simple-cipher/src/test/scala/CipherTest.scala +17 -9
  209. data/tracks/scala/exercises/sublist/src/test/scala/sublist_test.scala +17 -0
  210. data/tracks/scala/exercises/trinary/src/test/scala/TrinaryTest.scala +14 -7
  211. data/tracks/scala/exercises/wordy/src/test/scala/WordProblemTest.scala +28 -14
  212. data/tracks/scala/project/Build.scala +3 -3
  213. data/tracks/scala/testgen/src/main/scala/BowlingTestGenerator.scala +57 -0
  214. data/tracks/sml/config.json +41 -6
  215. data/tracks/sml/exercises/flatten-array/example.sml +6 -0
  216. data/tracks/sml/exercises/flatten-array/test_flatten_array.sml +10 -0
  217. data/tracks/sml/exercises/nth-prime/example.sml +46 -0
  218. data/tracks/sml/exercises/nth-prime/test_nth_prime.sml +14 -0
  219. data/tracks/sml/exercises/raindrops/example.sml +9 -0
  220. data/tracks/sml/exercises/raindrops/raindrops.sml +2 -0
  221. data/tracks/sml/exercises/raindrops/test_raindrops.sml +95 -0
  222. data/tracks/swift/config.json +269 -328
  223. data/tracks/swift/exercises/pangram/PangramExample.swift +17 -0
  224. data/tracks/swift/exercises/pangram/PangramTest.swift +43 -0
  225. data/tracks/swift/xcodeProject/xSwift.xcodeproj/project.pbxproj +16 -0
  226. metadata +95 -3
@@ -5,12 +5,18 @@ import (
5
5
  "strings"
6
6
  )
7
7
 
8
+ const testVersion = 2
9
+
10
+ // Histogram is a mapping from nucleotide to its count in given DNA
8
11
  type Histogram map[byte]int
9
12
 
13
+ // DNA is a list of nucleotides
10
14
  type DNA string
11
15
 
16
+ const validNucleotides = "ACGT"
17
+
18
+ // Count counts number of occurrences of given nucleotide in given DNA
12
19
  func (dna DNA) Count(nucleotide byte) (count int, err error) {
13
- validNucleotides := "ACGT"
14
20
  if !strings.Contains(validNucleotides, string(nucleotide)) {
15
21
  return 0, errors.New("dna: invalid nucleotide " + string(nucleotide))
16
22
  }
@@ -18,11 +24,18 @@ func (dna DNA) Count(nucleotide byte) (count int, err error) {
18
24
  return strings.Count(string(dna), string(nucleotide)), nil
19
25
  }
20
26
 
21
- func (dna DNA) Counts() Histogram {
22
- a, _ := dna.Count('A')
23
- c, _ := dna.Count('C')
24
- t, _ := dna.Count('T')
25
- g, _ := dna.Count('G')
26
-
27
- return Histogram{'A': a, 'C': c, 'T': t, 'G': g}
27
+ // Counts generates a histogram of valid nucleotides in given DNA.
28
+ // Returns error if DNA contains invalid nucleotide.
29
+ func (dna DNA) Counts() (Histogram, error) {
30
+ var total int
31
+ h := Histogram{}
32
+ for i := range validNucleotides {
33
+ nucleotide := validNucleotides[i]
34
+ h[nucleotide], _ = dna.Count(nucleotide)
35
+ total += h[nucleotide]
36
+ }
37
+ if total != len(dna) {
38
+ return nil, errors.New("dna: contains invalid nucleotide")
39
+ }
40
+ return h, nil
28
41
  }
@@ -1,27 +1,12 @@
1
1
  package dna
2
2
 
3
- import "testing"
4
-
5
- func (h Histogram) Equal(o Histogram) bool {
6
- return h.sameLength(o) && h.sameMappings(o)
7
- }
8
-
9
- func (h Histogram) sameLength(o Histogram) bool {
10
- return len(h) == len(o)
11
- }
12
-
13
- func (h Histogram) sameMappings(o Histogram) (res bool) {
14
- res = true
15
- for k := range h {
16
- if h[k] != o[k] {
17
- res = false
18
- }
19
- }
20
- return
21
- }
3
+ import (
4
+ "reflect"
5
+ "testing"
6
+ )
22
7
 
23
8
  var tallyTests = []struct {
24
- strand string
9
+ strand DNA
25
10
  nucleotide byte
26
11
  expected int
27
12
  }{
@@ -33,9 +18,9 @@ var tallyTests = []struct {
33
18
 
34
19
  func TestNucleotideCounts(t *testing.T) {
35
20
  for _, tt := range tallyTests {
36
- dna := DNA(tt.strand)
37
- count, _ := dna.Count(tt.nucleotide)
38
- if count != tt.expected {
21
+ if count, err := tt.strand.Count(tt.nucleotide); err != nil {
22
+ t.Fatal(err)
23
+ } else if count != tt.expected {
39
24
  t.Fatalf("Got \"%v\", expected \"%v\"", count, tt.expected)
40
25
  }
41
26
  }
@@ -43,11 +28,7 @@ func TestNucleotideCounts(t *testing.T) {
43
28
 
44
29
  func TestHasErrorForInvalidNucleotides(t *testing.T) {
45
30
  dna := DNA("GATTACA")
46
- count, err := dna.Count('X')
47
- if count != 0 {
48
- t.Fatalf("Got \"%v\", expected \"%v\"", count, 0)
49
- }
50
- if err == nil {
31
+ if _, err := dna.Count('X'); err == nil {
51
32
  t.Fatalf("X is an invalid nucleotide, but no error was raised")
52
33
  }
53
34
  }
@@ -58,37 +39,57 @@ func TestHasErrorForInvalidNucleotides(t *testing.T) {
58
39
  func TestCountingDoesntChangeCount(t *testing.T) {
59
40
  dna := DNA("CGATTGGG")
60
41
  dna.Count('T')
61
- count, _ := dna.Count('T')
62
- if count != 2 {
63
- t.Fatalf("Got \"%v\", expected \"%v\"", count, 2)
42
+ count1, err := dna.Count('T')
43
+ if err != nil {
44
+ t.Fatal(err)
45
+ }
46
+ count2, err := dna.Count('T')
47
+ if err != nil {
48
+ t.Fatal(err)
49
+ }
50
+ if count1 != count2 || count2 != 2 {
51
+ t.Fatalf("Got %v, expected %v", []int{count1, count2}, []int{2, 2})
64
52
  }
65
53
  }
66
54
 
67
55
  type histogramTest struct {
68
- strand string
56
+ strand DNA
69
57
  expected Histogram
58
+ err bool
70
59
  }
71
60
 
72
61
  var histogramTests = []histogramTest{
73
62
  {
74
63
  "",
75
64
  Histogram{'A': 0, 'C': 0, 'T': 0, 'G': 0},
65
+ false,
76
66
  },
77
67
  {
78
68
  "GGGGGGGG",
79
69
  Histogram{'A': 0, 'C': 0, 'T': 0, 'G': 8},
70
+ false,
80
71
  },
81
72
  {
82
73
  "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC",
83
74
  Histogram{'A': 20, 'C': 12, 'T': 21, 'G': 17},
75
+ false,
76
+ },
77
+ {
78
+ "GGXXX",
79
+ nil,
80
+ true,
84
81
  },
85
82
  }
86
83
 
87
84
  func TestSequenceHistograms(t *testing.T) {
88
85
  for _, tt := range histogramTests {
89
- dna := DNA(tt.strand)
90
- if !dna.Counts().Equal(tt.expected) {
91
- t.Fatalf("DNA{ \"%v\" }: Got \"%v\", expected \"%v\"", tt.strand, dna.Counts(), tt.expected)
86
+ counts, err := tt.strand.Counts()
87
+ if tt.err && err == nil {
88
+ t.Fatalf("DNA{ %q }: expected error but didn't get one.", tt.strand)
89
+ } else if !tt.err && err != nil {
90
+ t.Fatalf("DNA{ %q }: expected no error but got error %s", tt.strand, err.Error())
91
+ } else if !tt.err && !reflect.DeepEqual(counts, tt.expected) {
92
+ t.Fatalf("DNA{ %q }: Got %v, expected %v", tt.strand, counts, tt.expected)
92
93
  }
93
94
  }
94
95
  }
@@ -97,12 +98,19 @@ func BenchmarkSequenceHistograms(b *testing.B) {
97
98
  b.StopTimer()
98
99
  for _, tt := range histogramTests {
99
100
  for i := 0; i < b.N; i++ {
100
- dna := DNA(tt.strand)
101
101
  b.StartTimer()
102
102
 
103
- dna.Counts()
103
+ tt.strand.Counts()
104
104
 
105
105
  b.StopTimer()
106
106
  }
107
107
  }
108
108
  }
109
+
110
+ const targetTestVersion = 2
111
+
112
+ func TestTestVersion(t *testing.T) {
113
+ if testVersion != targetTestVersion {
114
+ t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
115
+ }
116
+ }
@@ -24,7 +24,7 @@ specs = describe "anagram" $
24
24
  . map fromList
25
25
  $ candidates
26
26
 
27
- -- Test cases adapted from `exercism/x-common/anagrams.json` on 2016-07-25.
27
+ -- Test cases adapted from `exercism/x-common` on 2016-10-26.
28
28
 
29
29
  data Case = Case { description :: String
30
30
  , subject :: String
@@ -108,16 +108,6 @@ cases = [ Case { description = "no matches"
108
108
  , candidates = ["patter"]
109
109
  , expected = []
110
110
  }
111
- , Case { description = "detects unicode anagrams"
112
- , subject = "ΑΒΓ"
113
- , candidates = ["ΒΓΑ", "ΒΓΔ", "γβα"]
114
- , expected = ["ΒΓΑ", "γβα"]
115
- }
116
- , Case { description = "eliminates misleading unicode anagrams"
117
- , subject = "ΑΒΓ"
118
- , candidates = ["ABΓ"]
119
- , expected = []
120
- }
121
111
  , Case { description = "capital word is not own anagram"
122
112
  , subject = "BANANA"
123
113
  , candidates = ["Banana"]
@@ -1,79 +1,67 @@
1
- #!/bin/bash
2
- SCRIPTPATH=$( pushd `dirname $0` > /dev/null && pwd && popd > /dev/null )
3
- EXECPATH=$PWD
4
- XAPI_PID=""
5
-
6
- # Makes CI output easier to read
7
- TERM=dumb
1
+ #!/usr/bin/env bash
8
2
 
9
- function on_exit() {
3
+ on_exit() {
10
4
  echo ">>> on_exit()"
11
- if [ "$XAPI_PID" != "" ] ; then
12
- kill $XAPI_PID
13
- echo "Stopped X-API (pid=${XAPI_PID})"
5
+ if [[ "$xapi_pid" != "" ]] ; then
6
+ kill $xapi_pid
7
+ echo "stopped x-api (pid=${xapi_pid})"
14
8
  fi
15
9
  cd $EXECPATH
16
10
  echo "<<< on_exit()"
17
11
  }
18
12
 
19
- assert_gradle_installed() {
20
- echo ">>> assert_gradle_installed()"
21
- which gradle >/dev/null
22
- if [ $? != 0 ]; then
23
- echo "Gradle not found. This the Java build tool and is required."
24
- echo -e "Have you completed the setup instructions at https://github.com/exercism/xjava ?\n"
25
- echo "PATH=${PATH}"
26
- echo "aborting."
27
- exit 1
28
- fi
29
- echo "<<< assert_gradle_installed()"
30
- }
13
+ assert_installed() {
14
+ local binary=$1
15
+ echo ">>> assert_installed(binary=\"${binary}\")"
31
16
 
32
- assert_jq_installed() {
33
- echo ">>> assert_jq_installed()"
34
- which jq >/dev/null
35
- if [ $? != 0 ]; then
36
- echo "jq not found. This utility is used to parse the config.json file and is required."
17
+ if [[ "`which $binary`" == "" ]]; then
18
+ echo "${binary} not found; it is required to perform this test."
37
19
  echo -e "Have you completed the setup instructions at https://github.com/exercism/xjava ?\n"
38
20
  echo "PATH=${PATH}"
39
21
  echo "aborting."
40
22
  exit 1
41
23
  fi
42
- echo "<<< assert_jq_installed()"
24
+ echo "<<< assert_installed()"
43
25
  }
44
26
 
45
- assert_required_ruby_installed() {
46
- echo ">>> assert_required_ruby_installed(\"$1\")"
47
- local RACKAPP_HOME="$1"
27
+ assert_ruby_installed() {
28
+ local ruby_app_home="$1"
29
+ echo ">>> assert_ruby_installed(ruby_app_home=\"${ruby_app_home}\")"
48
30
 
49
- pushd "${RACKAPP_HOME}" >/dev/null
50
- local CURRENT_RUBY_VER=`ruby --version | egrep --only-matching "[0-9]+\.[0-9]+\.[0-9]+"`
51
- local EXPECTED_RUBY_VER=`cat Gemfile | awk -F\' '/ruby /{print $2}'`
52
- popd >/dev/null
53
- if [ "$CURRENT_RUBY_VER" != "$EXPECTED_RUBY_VER" ]; then
54
- echo "${RACKAPP_HOME} requires Ruby ${EXPECTED_RUBY_VER}; current Ruby version is ${CURRENT_RUBY_VER}."
31
+ pushd "${ruby_app_home}"
32
+ local current_ruby_ver=`ruby --version | egrep --only-matching "[0-9]+\.[0-9]+\.[0-9]+"`
33
+ local expected_ruby_ver=`cat Gemfile | awk -F\' '/ruby /{print $2}'`
34
+ popd
35
+ if [[ "${expected_ruby_ver}" != "" && "${current_ruby_ver}" != "${expected_ruby_ver}" ]]; then
36
+ echo "${ruby_app_home} requires Ruby ${expected_ruby_ver}; current Ruby version is ${current_ruby_ver}."
55
37
  echo -e "Ruby used: `which ruby`.\n"
56
38
  echo -e "Have you completed the setup instructions at https://github.com/exercism/xjava ?\n"
57
39
  echo "PATH=${PATH}"
58
40
  echo "aborting."
59
41
  exit 1
60
42
  fi
61
- echo "<<< assert_required_ruby_installed()"
43
+ echo "<<< assert_ruby_installed()"
62
44
  }
63
45
 
64
- clean_build() {
65
- echo ">>> clean_build(\"$1\", \"$2\")"
66
- local REPO_ROOT="$1"
67
- local BUILD_DIR="$2"
46
+ clean() {
47
+ local build_dir="$1"
48
+ echo ">>> clean(build_dir=\"${build_dir}\")"
68
49
 
69
- if [ -d "$BUILD_DIR" ] ; then
70
- echo "Cleaning journey script build (${BUILD_DIR})."
71
- rm -rf "$BUILD_DIR"
50
+ # empty, absolute path, or parent reference are considered dangerous to rm -rf against.
51
+ if [[ "${build_dir}" == "" || ${build_dir} =~ ^/ || ${build_dir} =~ \.\. ]] ; then
52
+ echo "Value for build_dir looks dangerous. Aborting."
53
+ exit 1
54
+ fi
55
+
56
+ local build_path=$( pwd )/${build_dir}
57
+ if [[ -d "${build_path}" ]] ; then
58
+ echo "Cleaning journey script build output directory (${build_path})."
59
+ rm -rf "${build_path}"
72
60
  fi
73
- pushd ${REPO_ROOT}/exercises > /dev/null
61
+ cd exercises
74
62
  gradle clean
75
- popd > /dev/null
76
- echo "<<< clean_build()"
63
+ cd ..
64
+ echo "<<< clean()"
77
65
  }
78
66
 
79
67
  get_operating_system() {
@@ -102,131 +90,180 @@ get_cpu_architecture() {
102
90
  esac
103
91
  }
104
92
 
105
- fetch_exercism_cli() {
106
- echo ">>> fetch_exercism_cli(\"$1\", \"$2\", \"$3\")"
107
- local OS="$1"
108
- local ARCH="$2"
109
- local EXERCISM_HOME="$3"
93
+ download_exercism_cli() {
94
+ local os="$1"
95
+ local arch="$2"
96
+ local exercism_home="$3"
97
+ echo ">>> download_exercism_cli(os=\"${os}\", arch=\"${arch}\", exercism_home=\"${exercism_home}\")"
98
+
99
+ local CLI_RELEASES=https://github.com/exercism/cli/releases
110
100
 
111
- local LATEST=https://github.com/exercism/cli/releases/latest
101
+ local latest=${CLI_RELEASES}/latest
112
102
  # "curl..." :: HTTP 302 headers, including "Location" -- URL to redirect to.
113
103
  # "awk..." :: pluck last path segment from "Location" (i.e. the version number)
114
- local VERSION="$(curl --head --silent $LATEST | awk -v FS=/ '/Location:/{print $NF}' | tr -d '\r')"
115
- local CLI_URL=https://github.com/exercism/cli/releases/download/${VERSION}/exercism-${OS}-${ARCH}.tgz
104
+ local version="$(curl --head --silent ${latest} | awk -v FS=/ '/Location:/{print $NF}' | tr -d '\r')"
105
+ local download_url=${CLI_RELEASES}/download/${version}/exercism-${os}-${arch}.tgz
106
+
107
+ mkdir -p ${exercism_home}
108
+ curl -s --location ${download_url} | tar xz -C ${exercism_home}
109
+ echo "<<< download_exercism_cli()"
110
+ }
111
+
112
+ git_clone() {
113
+ local repo_name="$1"
114
+ local dest_path="$2"
115
+ echo ">>> git_clone(repo_name=\"${repo_name}\", dest_path=\"${dest_path}\")"
116
+
117
+ git clone https://github.com/exercism/${repo_name} ${dest_path}
116
118
 
117
- mkdir -p ${EXERCISM_HOME}
118
- curl -s --location ${CLI_URL} | tar xz -C ${EXERCISM_HOME}
119
- echo "<<< fetch_exercism_cli()"
119
+ echo "<<< git_clone()"
120
120
  }
121
121
 
122
- fetch_x_api() {
123
- echo ">>> fetch_x_api(\"$1\")"
124
- local XAPI_HOME="$1"
122
+ make_local_trackler() {
123
+ local trackler="$1"
124
+ echo ">>> make_local_trackler(trackler=\"${trackler}\")"
125
125
 
126
- git clone https://github.com/exercism/x-api ${XAPI_HOME}
127
- pushd ${XAPI_HOME} >/dev/null
128
- git submodule init -- metadata
126
+ local xjava=$( pwd )
127
+ pushd ${trackler}
128
+ git submodule init -- common
129
129
  git submodule update
130
+
131
+ # Bake in local copy of xjava; this is what we are testing.
130
132
  rmdir tracks/java
131
- ln -s $REPO_ROOT tracks/java
133
+ mkdir -p tracks/java/exercises
134
+ cp ${xjava}/config.json tracks/java
135
+ cp -r ${xjava}/exercises tracks/java
136
+
137
+ gem install bundler
138
+ bundle install
139
+ gem build trackler.gemspec
140
+
141
+ # Make *this* the gem that x-api uses when we build x-api.
142
+ gem install --local trackler-*.gem
143
+
132
144
  popd > /dev/null
133
- echo "<<< fetch_x_api()"
145
+ echo "<<< make_local_trackler()"
134
146
  }
135
147
 
136
148
  start_x_api() {
137
- echo ">>> start_x_api(\"$1\")"
138
- local XAPI_HOME="$1"
149
+ local xapi_home="$1"
150
+ echo ">>> start_x_api(xapi_home=\"${xapi_home}\")"
139
151
 
140
- pushd $XAPI_HOME >/dev/null
152
+ pushd $xapi_home
141
153
 
142
- SET_RUBY_VER_CMD="rbenv local 2.2.1"
143
154
  gem install bundler
144
155
  bundle install
145
-
146
156
  RACK_ENV=development rackup &
147
- XAPI_PID=$!
157
+ xapi_pid=$!
148
158
  sleep 5
149
159
 
150
- echo "X-API is running (pid=${XAPI_PID})."
160
+ echo "x-api is running (pid=${xapi_pid})."
151
161
 
152
162
  popd > /dev/null
153
163
  echo "<<< start_x_api()"
154
164
  }
155
165
 
156
166
  configure_exercism_cli() {
157
- echo ">>> configure_exercism_cli(\"$1\", \"$2\", $3)"
158
- local EXERCISM_HOME="$1"
159
- local EXERCISM_CONFIGFILE="$2"
160
- local XAPI_PORT=$3
161
- local EXERCISM="./exercism --config ${EXERCISM_CONFIGFILE}"
162
-
163
- mkdir -p "${EXERCISM_HOME}"
164
- pushd "${EXERCISM_HOME}" >/dev/null
165
- $EXERCISM configure --dir="${EXERCISM_HOME}"
166
- $EXERCISM configure --api http://localhost:${XAPI_PORT}
167
- $EXERCISM debug
168
- popd >/dev/null
167
+ local exercism_home="$1"
168
+ local exercism_configfile="$2"
169
+ local xapi_port=$3
170
+ echo ">>> configure_exercism_cli(exercism_home=\"${exercism_home}\", exercism_configfile=\"${exercism_configfile}\", xapi_port=${xapi_port})"
171
+ local exercism="./exercism --config ${exercism_configfile}"
172
+
173
+ mkdir -p "${exercism_home}"
174
+ pushd "${exercism_home}"
175
+ $exercism configure --dir="${exercism_home}"
176
+ $exercism configure --api http://localhost:${xapi_port}
177
+ $exercism debug
178
+ popd
169
179
 
170
180
  echo "<<< configure_exercism_cli()"
171
181
  }
172
182
 
173
183
  solve_all_exercises() {
174
- echo ">>> solve_all_exercises(\"$1\", \"$2\")"
175
-
176
- local EXERCISM_HOME="$1"
177
- local EXERCISM_CONFIGFILE="$2"
178
-
179
- local EXERCISM="./exercism --config ${EXERCISM_CONFIGFILE}"
180
- local EXERCISES=`cat config.json | jq '.problems []' --raw-output`
181
- local TOTAL_EXERCISES=`cat config.json | jq '.problems | length'`
182
- local CURRENT_EXERCISE_NUMBER=1
183
- local TEMPFILE="${TMPDIR:-/tmp}/journey-test.sh-unignore_all_tests.txt"
184
-
185
- pushd ${EXERCISM_HOME} >/dev/null
186
- for EXERCISE in $EXERCISES; do
187
- echo ''
188
- echo '****' Testing $EXERCISE '('$CURRENT_EXERCISE_NUMBER / $TOTAL_EXERCISES') ****'
189
- echo ''
190
- $EXERCISM fetch java $EXERCISE
191
- cp -R -H $REPO_ROOT/exercises/$EXERCISE/src/example/java/* $EXERCISM_HOME/java/$EXERCISE/src/main/java/
192
- pushd $EXERCISM_HOME/java/$EXERCISE/ >/dev/null
193
- for TESTFILE in `find . -name "*Test.java"`; do
194
- sed 's/@Ignore//' $TESTFILE > "$TEMPFILE" && mv "$TEMPFILE" "$TESTFILE"
184
+ local exercism_exercises_dir="$1"
185
+ local exercism_configfile="$2"
186
+ echo ">>> solve_all_exercises(exercism_exercises_dir=\"${exercism_exercises_dir}\", exercism_configfile=\"${exercism_configfile}\")"
187
+
188
+ local xjava=$( pwd )
189
+ local exercism_cli="./exercism --config ${exercism_configfile}"
190
+ local exercises=`cat config.json | jq '.problems []' --raw-output`
191
+ local total_exercises=`cat config.json | jq '.problems | length'`
192
+ local current_exercise_number=1
193
+ local tempfile="${TMPDIR:-/tmp}/journey-test.sh-unignore_all_tests.txt"
194
+
195
+ pushd ${exercism_exercises_dir}
196
+ for exercise in $exercises; do
197
+ echo -e "\n\n"
198
+ echo "=================================================="
199
+ echo "${current_exercise_number} of ${total_exercises} -- ${exercise}"
200
+ echo "=================================================="
201
+
202
+ ${exercism_cli} fetch java $exercise
203
+ cp -R -H ${xjava}/exercises/${exercise}/src/example/java/* ${exercism_exercises_dir}/java/${exercise}/src/main/java/
204
+
205
+ pushd ${exercism_exercises_dir}/java/${exercise}
206
+ # Ensure we run all the tests (as delivered, all but the first is @Ignore'd)
207
+ for testfile in `find . -name "*Test.java"`; do
208
+ sed 's/@Ignore//' ${testfile} > "${tempfile}" && mv "${tempfile}" "${testfile}"
195
209
  done
196
210
  gradle test
197
- popd >/dev/null
211
+ popd
198
212
 
199
- CURRENT_EXERCISE_NUMBER=$((CURRENT_EXERCISE_NUMBER + 1))
213
+ current_exercise_number=$((current_exercise_number + 1))
200
214
  done
201
- popd >/dev/null
215
+ popd
202
216
  }
203
217
 
204
218
  main() {
205
- # allow all functions to assume current working directory is repository root.
219
+ # all functions assume current working directory is repository root.
206
220
  cd "${SCRIPTPATH}/.."
207
221
 
208
- local REPO_ROOT="${PWD}"
209
- local BUILD_DIR="${REPO_ROOT}/build"
210
- local XAPI_HOME="${BUILD_DIR}/x-api"
211
- local EXERCISM_HOME="${BUILD_DIR}/exercism"
212
- local EXERCISM_CONFIGFILE=".journey-test.exercism.json"
213
- local XAPI_PORT=9292
214
-
215
- assert_gradle_installed
216
- assert_jq_installed
217
- clean_build "${REPO_ROOT}" "${BUILD_DIR}"
218
- fetch_exercism_cli $(get_operating_system) $(get_cpu_architecture) "${EXERCISM_HOME}"
219
- fetch_x_api "${XAPI_HOME}"
220
- assert_required_ruby_installed "${XAPI_HOME}"
221
- start_x_api "${XAPI_HOME}"
222
- configure_exercism_cli "${EXERCISM_HOME}" "${EXERCISM_CONFIGFILE}" "${XAPI_PORT}"
223
- solve_all_exercises "${EXERCISM_HOME}" "${EXERCISM_CONFIGFILE}"
222
+ local xjava=$( pwd )
223
+ local build_dir="build"
224
+ local build_path="${xjava}/${build_dir}"
225
+
226
+ local xapi_home="${build_path}/x-api"
227
+ local trackler_home="${build_path}/trackler"
228
+ local exercism_home="${build_path}/exercism"
229
+
230
+ local exercism_configfile=".journey-test.exercism.json"
231
+ local xapi_port=9292
232
+
233
+ # fail fast if required binaries are not installed.
234
+ assert_installed "gradle"
235
+ assert_installed "jq"
236
+
237
+ clean "${build_dir}"
238
+
239
+ # Make a version of trackler that includes the source from this repo.
240
+ git_clone "trackler" "${trackler_home}"
241
+ assert_ruby_installed "${trackler_home}"
242
+ make_local_trackler "${trackler_home}"
243
+
244
+ # Stand-up a local instance of x-api so we can fetch the exercises through it.
245
+ git_clone "x-api" "${xapi_home}"
246
+ assert_ruby_installed "${xapi_home}"
247
+ start_x_api "${xapi_home}"
248
+
249
+ # Create a CLI install and config just for this build; this script does not use your CLI install.
250
+ download_exercism_cli $(get_operating_system) $(get_cpu_architecture) "${exercism_home}"
251
+ configure_exercism_cli "${exercism_home}" "${exercism_configfile}" "${xapi_port}"
252
+
253
+ solve_all_exercises "${exercism_home}" "${exercism_configfile}"
224
254
  }
225
255
 
226
256
  ##########################################################################
227
257
  # Execution begins here...
228
258
 
259
+ # If any command fails, fail the script.
229
260
  set -e
261
+ SCRIPTPATH=$( pushd `dirname $0` > /dev/null && pwd && popd > /dev/null )
262
+ EXECPATH=$( pwd )
263
+ # Make output easier to read in CI
264
+ TERM=dumb
265
+
266
+ xapi_pid=""
230
267
  trap on_exit EXIT
231
268
  main
232
269
 
@@ -18,15 +18,12 @@ The language derives much of its syntax from C and C++, but it has fewer low-lev
18
18
 
19
19
  ## Why Learn JAVA?
20
20
 
21
- - JAVA IS EVERYWHERE. It is one of the most sought after programming languages, as it is a standard for enterprise software, web-based content, games and mobile apps, as well as the [Android operating system](https://developer.android.com/index.html).
22
-
23
- - [Write once, run anywhere](https://en.wikipedia.org/wiki/Write_once,_run_anywhere) policy : Programs written in Java, are compiled into machine-independent bytecodes, so it can run on any Java platform.Basically, Java is [Platform Independent](https://en.wikipedia.org/wiki/Cross-platform#Platform-independent_software)
24
-
25
- - Java has a Rich API:
26
- Java provides [API](https://en.wikipedia.org/wiki/Application_programming_interface)'s(Application Programming Interface) for I/O, networking, utilities, XML parsing, database connections, and many other functions. Standard libraries can be supplemented by open source libraries like Apache Commons, Google Guava and others.
21
+ - JAVA IS EVERYWHERE. It is one of the most sought after programming languages. It is a standard for enterprise software, web-based content, games and mobile apps, as well as the [Android operating system](https://developer.android.com/index.html).
27
22
 
23
+ - [Write once, run anywhere](https://en.wikipedia.org/wiki/Write_once,_run_anywhere) policy: Programs written in Java are compiled into machine-independent bytecodes, so it can run on any Java platform. Basically, Java is [Platform Independent](https://en.wikipedia.org/wiki/Cross-platform#Platform-independent_software)
28
24
 
25
+ - Java has rich APIs:
26
+ Java has built-in [application programming interfaces](https://en.wikipedia.org/wiki/Application_programming_interface) (APIs) for I/O, networking, data structures, concurrency, and many other functions. Standard libraries can be supplemented by open source libraries like Apache Commons, Google Guava, Netty and others.
29
27
 
30
28
  - Standardization:
31
- If you need to write a web/enterprise app, or you need data persistence or you need to do cryptography, no problem! Java is all you require.There are several other standardized stuff in the Java ecosystem, thanks to the [JCP](https://www.jcp.org/en/introduction/overview) (Java Community Process)!
32
-
29
+ If you need to write a web/enterprise app, or you need data persistence or you need to do cryptography, no problem! Java is all you require. There are many standard tools/practices that extend the Java ecosystem, thanks to the [Java Community Process](https://www.jcp.org/en/introduction/overview) (JCP)!
@@ -16,9 +16,3 @@ test {
16
16
  events = ["passed", "failed", "skipped"]
17
17
  }
18
18
  }
19
- test {
20
- testLogging {
21
- exceptionFormat = 'full'
22
- events = ["passed", "failed", "skipped"]
23
- }
24
- }
@@ -1,6 +1,5 @@
1
1
  import org.junit.Test;
2
2
  import org.junit.Ignore;
3
- import org.junit.Ignore;
4
3
 
5
4
  import static org.junit.Assert.assertEquals;
6
5
 
@@ -7,7 +7,6 @@ repositories {
7
7
  }
8
8
 
9
9
  dependencies {
10
- compile "joda-time:joda-time:2.3+"
11
10
  testCompile "junit:junit:4.10"
12
11
  testCompile "org.assertj:assertj-core:3.2.0"
13
12
  }