trackler 1.0.1.0 → 1.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/bin/bump-content +33 -0
  4. data/common/exercises/bowling/canonical-data.json +78 -77
  5. data/common/exercises/counter/.deprecated +1 -0
  6. data/common/exercises/point-mutations/.deprecated +1 -0
  7. data/common/exercises/say/canonical-data.json +83 -0
  8. data/common/exercises/word-count/canonical-data.json +25 -5
  9. data/lib/trackler/version.rb +1 -1
  10. data/tracks/c/config.json +9 -0
  11. data/tracks/c/exercises/largest-series-product/makefile +16 -0
  12. data/tracks/c/exercises/largest-series-product/src/example.c +54 -0
  13. data/tracks/c/exercises/largest-series-product/src/example.h +9 -0
  14. data/tracks/c/exercises/largest-series-product/test/test_largest_series_product.c +114 -0
  15. data/tracks/c/exercises/largest-series-product/test/vendor/unity.c +1300 -0
  16. data/tracks/c/exercises/largest-series-product/test/vendor/unity.h +274 -0
  17. data/tracks/c/exercises/largest-series-product/test/vendor/unity_internals.h +701 -0
  18. data/tracks/clojure/_test/check_exercises.clj +7 -6
  19. data/tracks/clojure/config.json +268 -53
  20. data/tracks/clojure/exercises/flatten-array/src/example.clj +16 -0
  21. data/tracks/clojure/exercises/flatten-array/test/flatten_array_test.clj +28 -0
  22. data/tracks/clojure/exercises/perfect-numbers/project.clj +4 -0
  23. data/tracks/clojure/exercises/perfect-numbers/src/example.clj +17 -0
  24. data/tracks/clojure/exercises/perfect-numbers/test/perfect_numbers_test.clj +20 -0
  25. data/tracks/ecmascript/exercises/grade-school/grade-school.spec.js +7 -0
  26. data/tracks/elixir/.travis.yml +3 -0
  27. data/tracks/elixir/bin/dialyzer_check.sh +28 -0
  28. data/tracks/elixir/config.json +13 -1
  29. data/tracks/elixir/docs/TESTS.md +81 -0
  30. data/tracks/elixir/exercises/bank-account/example.exs +1 -1
  31. data/tracks/elixir/exercises/binary-search/binary_search_test.exs +5 -0
  32. data/tracks/elixir/exercises/clock/clock.exs +23 -0
  33. data/tracks/elixir/exercises/clock/clock_test.exs +281 -0
  34. data/tracks/elixir/exercises/clock/example.exs +55 -0
  35. data/tracks/elixir/exercises/prime-factors/example.exs +1 -2
  36. data/tracks/elixir/exercises/robot-simulator/example.exs +2 -3
  37. data/tracks/elixir/mix.exs +2 -1
  38. data/tracks/go/docs/TESTS.md +1 -1
  39. data/tracks/go/exercises/gigasecond/gigasecond_test.go +0 -2
  40. data/tracks/go/exercises/palindrome-products/palindrome_products_test.go +38 -22
  41. data/tracks/haskell/.travis.yml +26 -7
  42. data/tracks/haskell/config.json +0 -69
  43. data/tracks/haskell/exercises/anagram/examples/list-string/Anagram.hs +10 -0
  44. data/tracks/haskell/exercises/anagram/examples/list-string/package.yaml +17 -0
  45. data/tracks/haskell/exercises/anagram/{src/Example.hs → examples/set-text/Anagram.hs} +0 -0
  46. data/tracks/haskell/exercises/anagram/examples/set-text/package.yaml +20 -0
  47. data/tracks/haskell/exercises/anagram/package.yaml +0 -3
  48. data/tracks/idris/config.json +3 -3
  49. data/tracks/kotlin/config.json +207 -43
  50. data/tracks/lfe/config.json +152 -32
  51. data/tracks/lfe/docs/TESTS.md +18 -56
  52. data/tracks/lua/docs/ABOUT.md +9 -0
  53. data/tracks/mips/config.json +72 -16
  54. data/tracks/ocaml/config.json +6 -0
  55. data/tracks/ocaml/exercises/etl/.merlin +5 -0
  56. data/tracks/ocaml/exercises/etl/Makefile +11 -0
  57. data/tracks/ocaml/exercises/etl/etl.mli +2 -0
  58. data/tracks/ocaml/exercises/etl/example.ml +7 -0
  59. data/tracks/ocaml/exercises/etl/test.ml +35 -0
  60. data/tracks/ocaml/exercises/raindrops/test.ml +1 -1
  61. data/tracks/php/config.json +7 -1
  62. data/tracks/php/exercises/acronym/acronym_test.php +56 -0
  63. data/tracks/php/exercises/acronym/example.php +20 -0
  64. data/tracks/racket/config.json +109 -22
  65. data/tracks/ruby/README.md +3 -3
  66. data/tracks/ruby/bin/generate +16 -0
  67. data/tracks/ruby/exercises/alphametics/.version +1 -1
  68. data/tracks/ruby/exercises/alphametics/alphametics_test.rb +24 -22
  69. data/tracks/ruby/exercises/alphametics/example.rb +1 -1
  70. data/tracks/ruby/lib/bracket_push_cases.rb +3 -3
  71. data/tracks/ruby/lib/{raindrop_cases.rb → raindrops_cases.rb} +1 -1
  72. data/tracks/rust/config.json +1 -0
  73. data/tracks/rust/exercises/atbash-cipher/Cargo.lock +4 -0
  74. data/tracks/rust/exercises/atbash-cipher/Cargo.toml +3 -0
  75. data/tracks/rust/exercises/atbash-cipher/example.rs +36 -0
  76. data/tracks/rust/exercises/atbash-cipher/tests/atbash-cipher.rs +82 -0
  77. data/tracks/rust/problems.md +1 -0
  78. data/tracks/scala/config.json +8 -0
  79. data/tracks/scala/exercises/sum-of-multiples/build.sbt +3 -0
  80. data/tracks/scala/exercises/sum-of-multiples/example.scala +10 -0
  81. data/tracks/scala/exercises/sum-of-multiples/src/main/scala/.keep +0 -0
  82. data/tracks/scala/exercises/sum-of-multiples/src/test/scala/SumOfMultiplesTest.scala +62 -0
  83. metadata +43 -23
  84. data/tracks/ruby/bin/generate-acronym +0 -7
  85. data/tracks/ruby/bin/generate-alphametics +0 -8
  86. data/tracks/ruby/bin/generate-binary +0 -7
  87. data/tracks/ruby/bin/generate-bracket-push +0 -7
  88. data/tracks/ruby/bin/generate-clock +0 -7
  89. data/tracks/ruby/bin/generate-connect +0 -7
  90. data/tracks/ruby/bin/generate-custom-set +0 -7
  91. data/tracks/ruby/bin/generate-difference-of-squares +0 -7
  92. data/tracks/ruby/bin/generate-gigasecond +0 -7
  93. data/tracks/ruby/bin/generate-hamming +0 -7
  94. data/tracks/ruby/bin/generate-hello-world +0 -7
  95. data/tracks/ruby/bin/generate-largest-series-product +0 -7
  96. data/tracks/ruby/bin/generate-leap +0 -7
  97. data/tracks/ruby/bin/generate-nth-prime +0 -7
  98. data/tracks/ruby/bin/generate-pangram +0 -7
  99. data/tracks/ruby/bin/generate-raindrops +0 -7
  100. data/tracks/ruby/bin/generate-rna-transcription +0 -7
  101. data/tracks/ruby/bin/generate-roman-numerals +0 -7
  102. data/tracks/ruby/bin/generate-run-length-encoding +0 -7
  103. data/tracks/ruby/bin/generate-two-bucket +0 -7
@@ -6,9 +6,10 @@
6
6
  (defn- ->snake_case [s] (string/replace s \- \_))
7
7
 
8
8
  (deftest check-exercises
9
- (doseq [problem ((json/parse-string (slurp "config.json")) "problems")
10
- :let [path-to-problem (partial str "exercises/" problem "/")
11
- problem-tests (symbol (str problem "-test"))]]
12
- (load-file (path-to-problem "src/example.clj"))
13
- (load-file (path-to-problem "test/" (->snake_case problem) "_test.clj"))
14
- (is (successful? (run-tests problem-tests)))))
9
+ (doseq [exercise ((json/parse-string (slurp "config.json")) "exercises")
10
+ :let [slug (exercise "slug")
11
+ path-to-exercise (partial str "exercises/" slug "/")
12
+ exercise-tests (symbol (str slug "-test"))]]
13
+ (load-file (path-to-exercise "src/example.clj"))
14
+ (load-file (path-to-exercise "test/" (->snake_case slug) "_test.clj"))
15
+ (is (successful? (run-tests exercise-tests)))))
@@ -3,59 +3,6 @@
3
3
  "language": "Clojure",
4
4
  "repository": "https://github.com/exercism/xclojure",
5
5
  "active": true,
6
- "problems": [
7
- "hello-world",
8
- "bob",
9
- "rna-transcription",
10
- "word-count",
11
- "anagram",
12
- "beer-song",
13
- "nucleotide-count",
14
- "hamming",
15
- "phone-number",
16
- "grade-school",
17
- "robot-name",
18
- "leap",
19
- "etl",
20
- "binary-search",
21
- "meetup",
22
- "space-age",
23
- "grains",
24
- "gigasecond",
25
- "triangle",
26
- "scrabble-score",
27
- "roman-numerals",
28
- "binary",
29
- "trinary",
30
- "prime-factors",
31
- "raindrops",
32
- "allergies",
33
- "octal",
34
- "strain",
35
- "atbash-cipher",
36
- "bank-account",
37
- "crypto-square",
38
- "pascals-triangle",
39
- "sum-of-multiples",
40
- "sieve",
41
- "luhn",
42
- "kindergarten-garden",
43
- "robot-simulator",
44
- "queen-attack",
45
- "accumulate",
46
- "binary-search-tree",
47
- "difference-of-squares",
48
- "hexadecimal",
49
- "all-your-base",
50
- "largest-series-product",
51
- "pov",
52
- "bracket-push",
53
- "minesweeper",
54
- "change",
55
- "pangram",
56
- "wordy",
57
- "isogram"
58
- ],
59
6
  "deprecated": [
60
7
 
61
8
  ],
@@ -66,5 +13,273 @@
66
13
  "img"
67
14
  ],
68
15
  "foregone": [
16
+
17
+ ],
18
+ "exercises": [
19
+ {
20
+ "difficulty": 1,
21
+ "slug": "hello-world",
22
+ "topics": []
23
+ },
24
+ {
25
+ "difficulty": 1,
26
+ "slug": "bob",
27
+ "topics": []
28
+ },
29
+ {
30
+ "difficulty": 1,
31
+ "slug": "rna-transcription",
32
+ "topics": []
33
+ },
34
+ {
35
+ "difficulty": 1,
36
+ "slug": "word-count",
37
+ "topics": []
38
+ },
39
+ {
40
+ "difficulty": 1,
41
+ "slug": "anagram",
42
+ "topics": []
43
+ },
44
+ {
45
+ "difficulty": 1,
46
+ "slug": "beer-song",
47
+ "topics": []
48
+ },
49
+ {
50
+ "difficulty": 1,
51
+ "slug": "nucleotide-count",
52
+ "topics": []
53
+ },
54
+ {
55
+ "difficulty": 1,
56
+ "slug": "hamming",
57
+ "topics": []
58
+ },
59
+ {
60
+ "difficulty": 1,
61
+ "slug": "phone-number",
62
+ "topics": []
63
+ },
64
+ {
65
+ "difficulty": 1,
66
+ "slug": "grade-school",
67
+ "topics": []
68
+ },
69
+ {
70
+ "difficulty": 1,
71
+ "slug": "robot-name",
72
+ "topics": []
73
+ },
74
+ {
75
+ "difficulty": 1,
76
+ "slug": "leap",
77
+ "topics": []
78
+ },
79
+ {
80
+ "difficulty": 1,
81
+ "slug": "etl",
82
+ "topics": []
83
+ },
84
+ {
85
+ "difficulty": 1,
86
+ "slug": "flatten-array",
87
+ "topics": []
88
+ },
89
+ {
90
+ "difficulty": 1,
91
+ "slug": "binary-search",
92
+ "topics": []
93
+ },
94
+ {
95
+ "difficulty": 1,
96
+ "slug": "perfect-numbers",
97
+ "topics": []
98
+ },
99
+ {
100
+ "difficulty": 1,
101
+ "slug": "meetup",
102
+ "topics": []
103
+ },
104
+ {
105
+ "difficulty": 1,
106
+ "slug": "space-age",
107
+ "topics": []
108
+ },
109
+ {
110
+ "difficulty": 1,
111
+ "slug": "grains",
112
+ "topics": []
113
+ },
114
+ {
115
+ "difficulty": 1,
116
+ "slug": "gigasecond",
117
+ "topics": []
118
+ },
119
+ {
120
+ "difficulty": 1,
121
+ "slug": "triangle",
122
+ "topics": []
123
+ },
124
+ {
125
+ "difficulty": 1,
126
+ "slug": "scrabble-score",
127
+ "topics": []
128
+ },
129
+ {
130
+ "difficulty": 1,
131
+ "slug": "roman-numerals",
132
+ "topics": []
133
+ },
134
+ {
135
+ "difficulty": 1,
136
+ "slug": "binary",
137
+ "topics": []
138
+ },
139
+ {
140
+ "difficulty": 1,
141
+ "slug": "trinary",
142
+ "topics": []
143
+ },
144
+ {
145
+ "difficulty": 1,
146
+ "slug": "prime-factors",
147
+ "topics": []
148
+ },
149
+ {
150
+ "difficulty": 1,
151
+ "slug": "raindrops",
152
+ "topics": []
153
+ },
154
+ {
155
+ "difficulty": 1,
156
+ "slug": "allergies",
157
+ "topics": []
158
+ },
159
+ {
160
+ "difficulty": 1,
161
+ "slug": "octal",
162
+ "topics": []
163
+ },
164
+ {
165
+ "difficulty": 1,
166
+ "slug": "strain",
167
+ "topics": []
168
+ },
169
+ {
170
+ "difficulty": 1,
171
+ "slug": "atbash-cipher",
172
+ "topics": []
173
+ },
174
+ {
175
+ "difficulty": 1,
176
+ "slug": "bank-account",
177
+ "topics": []
178
+ },
179
+ {
180
+ "difficulty": 1,
181
+ "slug": "crypto-square",
182
+ "topics": []
183
+ },
184
+ {
185
+ "difficulty": 1,
186
+ "slug": "pascals-triangle",
187
+ "topics": []
188
+ },
189
+ {
190
+ "difficulty": 1,
191
+ "slug": "sum-of-multiples",
192
+ "topics": []
193
+ },
194
+ {
195
+ "difficulty": 1,
196
+ "slug": "sieve",
197
+ "topics": []
198
+ },
199
+ {
200
+ "difficulty": 1,
201
+ "slug": "luhn",
202
+ "topics": []
203
+ },
204
+ {
205
+ "difficulty": 1,
206
+ "slug": "kindergarten-garden",
207
+ "topics": []
208
+ },
209
+ {
210
+ "difficulty": 1,
211
+ "slug": "robot-simulator",
212
+ "topics": []
213
+ },
214
+ {
215
+ "difficulty": 1,
216
+ "slug": "queen-attack",
217
+ "topics": []
218
+ },
219
+ {
220
+ "difficulty": 1,
221
+ "slug": "accumulate",
222
+ "topics": []
223
+ },
224
+ {
225
+ "difficulty": 1,
226
+ "slug": "binary-search-tree",
227
+ "topics": []
228
+ },
229
+ {
230
+ "difficulty": 1,
231
+ "slug": "difference-of-squares",
232
+ "topics": []
233
+ },
234
+ {
235
+ "difficulty": 1,
236
+ "slug": "hexadecimal",
237
+ "topics": []
238
+ },
239
+ {
240
+ "difficulty": 1,
241
+ "slug": "all-your-base",
242
+ "topics": []
243
+ },
244
+ {
245
+ "difficulty": 1,
246
+ "slug": "largest-series-product",
247
+ "topics": []
248
+ },
249
+ {
250
+ "difficulty": 1,
251
+ "slug": "pov",
252
+ "topics": []
253
+ },
254
+ {
255
+ "difficulty": 1,
256
+ "slug": "bracket-push",
257
+ "topics": []
258
+ },
259
+ {
260
+ "difficulty": 1,
261
+ "slug": "minesweeper",
262
+ "topics": []
263
+ },
264
+ {
265
+ "difficulty": 1,
266
+ "slug": "change",
267
+ "topics": []
268
+ },
269
+ {
270
+ "difficulty": 1,
271
+ "slug": "pangram",
272
+ "topics": []
273
+ },
274
+ {
275
+ "difficulty": 1,
276
+ "slug": "wordy",
277
+ "topics": []
278
+ },
279
+ {
280
+ "difficulty": 1,
281
+ "slug": "isogram",
282
+ "topics": []
283
+ }
69
284
  ]
70
285
  }
@@ -0,0 +1,16 @@
1
+ (ns flatten-array
2
+ (:refer-clojure :exclude [flatten]))
3
+
4
+ (defn flatten
5
+ "Flattens the given list and removes any nil values"
6
+ [coll]
7
+ (loop
8
+ [results nil
9
+ [elem & remaining] coll]
10
+ (if (or elem remaining)
11
+ (if (coll? elem)
12
+ (if (empty? elem)
13
+ (recur results remaining)
14
+ (recur results (conj remaining (rest elem) (first elem))))
15
+ (recur (conj results elem) remaining))
16
+ (reverse (remove nil? results)))))
@@ -0,0 +1,28 @@
1
+ (ns flatten-array-test
2
+ (require [clojure.test :refer [deftest is testing]]
3
+ [flatten-array]))
4
+
5
+ (deftest flattens-array-of-ints
6
+ (testing "flattens array with just integers present"
7
+ (is (= [1 2 3 4 5 6 7 8]
8
+ (flatten-array/flatten [1 [2 3 4 5 6 7] 8])))))
9
+
10
+ (deftest five-level-nesting
11
+ (testing "5 level nested list"
12
+ (is (= [0 2 2 3 8 100 4 50 -2]
13
+ (flatten-array/flatten [0 2 [[2 3] 8 100 4 [[[50]]]] -2])))))
14
+
15
+ (deftest six-level-nesting
16
+ (testing "6 level nested list"
17
+ (is (= [1 2 3 4 5 6 7 8]
18
+ (flatten-array/flatten [1 [2 [[3]] [4 [[5]]] 6 7] 8])))))
19
+
20
+ (deftest six-level-nested-with-nils
21
+ (testing "6 level nested list with nil values"
22
+ (is (= [0 2 2 3 8 100 -2]
23
+ (flatten-array/flatten [0 2 [[2 3] 8 [[100]] nil [[nil]]] -2])))))
24
+
25
+ (deftest all-nils-list
26
+ (testing "All values in nested list are nil"
27
+ (is (empty?
28
+ (flatten-array/flatten [nil [[[nil]]] nil nil [[nil nil] nil] nil])))))
@@ -0,0 +1,4 @@
1
+ (defproject perfect-numbers "0.1.0-SNAPSHOT"
2
+ :description "perfect-numbers exercise."
3
+ :url "https://github.com/exercism/xclojure/tree/master/exercises/perfect-numbers"
4
+ :dependencies [[org.clojure/clojure "1.8.0"]])
@@ -0,0 +1,17 @@
1
+ (ns perfect-numbers)
2
+
3
+ (defn- get-divisors
4
+ "Utility function to get the divisors of a number"
5
+ [number]
6
+ (for [n (range 1 (inc (quot number 2))) :when (zero? (mod number n))]
7
+ n))
8
+
9
+ (defn classify [number]
10
+ "Classifies a positive integer as deficient, abundant or perfect"
11
+ (if-not (pos? number)
12
+ (throw (IllegalArgumentException. "Only positive numbers can be classified."))
13
+ (let [divisor-sum (apply + (get-divisors number))]
14
+ (cond
15
+ (> divisor-sum number) :abundant
16
+ (< divisor-sum number) :deficient
17
+ (= divisor-sum number) :perfect))))
@@ -0,0 +1,20 @@
1
+ (ns perfect-numbers-test
2
+ (:require
3
+ [clojure.test :refer [deftest testing is]]
4
+ [perfect-numbers]))
5
+
6
+ (deftest test-initialize-perfect-number
7
+ (testing "Negative numbers throw an exception"
8
+ (is (thrown? IllegalArgumentException (perfect-numbers/classify -1)))))
9
+
10
+ (deftest test-classify-deficient
11
+ (testing "13 is a deficient number"
12
+ (is (= :deficient (perfect-numbers/classify 13)))))
13
+
14
+ (deftest test-classify-perfect
15
+ (testing "28 is a perfect number"
16
+ (is (= :perfect (perfect-numbers/classify 28)))))
17
+
18
+ (deftest test-classify-abundant
19
+ (testing "12 is an abundant number"
20
+ (is (= :abundant (perfect-numbers/classify 12)))))
@@ -70,4 +70,11 @@ describe('School', () => {
70
70
  expect(school.roster()).toEqual(expectedDb);
71
71
  });
72
72
 
73
+ xit('roster cannot be modified outside of module using grade()', () => {
74
+ school.add('Aimee', 2);
75
+ school.grade(2).push('Oops.');
76
+ const expectedDb = { 2 : [ 'Aimee' ] };
77
+ expect(school.roster()).toEqual(expectedDb);
78
+ });
79
+
73
80
  });
@@ -16,5 +16,8 @@ script:
16
16
  - EXERCISM_TEST_EXAMPLES=true elixirc --warnings-as-errors **/example.exs **/*_test.exs -o ./tmp > /dev/null
17
17
  - rm -rf ./tmp
18
18
 
19
+ - bin/dialyzer_check.sh
20
+
19
21
  - "! git grep ' $' -- \\*.exs | grep -v -e 'exercises/diamond/diamond_test.exs'"
22
+
20
23
  sudo: false
@@ -0,0 +1,28 @@
1
+ mkdir -p ./tmp/src
2
+ mkdir ./tmp/build
3
+
4
+
5
+ for example_file in exercises/**/example.exs
6
+ do
7
+ exercise_dir=$(dirname $example_file)
8
+ exercise=$(basename $exercise_dir)
9
+ cp "$exercise_dir/example.exs" "./tmp/src/$exercise.exs"
10
+ done
11
+
12
+ elixirc -o ./tmp/build ./tmp/src/*.exs
13
+
14
+ if [ $CI ]; then
15
+ export PLT_FILENAME=elixir-${TRAVIS_ELIXIR_VERSION:=1.3.2}_${TRAVIS_OTP_RELEASE:=19.0}.plt
16
+ export PLT_LOCATION=./tmp/$PLT_FILENAME
17
+ wget -O $PLT_LOCATION https://github.com/danielberkompas/travis_elixir_plts/blob/master/elixir-${TRAVIS_ELIXIR_VERSION}_${TRAVIS_OTP_RELEASE}.plt?raw=true
18
+
19
+ dialyzer --no_check_plt --plt $PLT_LOCATION --no_native ./tmp/build;
20
+ RESULT=$?
21
+ else
22
+ dialyzer ./tmp/build;
23
+ RESULT=$?
24
+ fi
25
+
26
+ rm -rf ./tmp
27
+
28
+ exit $RESULT
@@ -66,7 +66,8 @@
66
66
  "dot-dsl",
67
67
  "custom-set",
68
68
  "forth",
69
- "pangram"
69
+ "pangram",
70
+ "clock"
70
71
  ],
71
72
  "exercises": [
72
73
  {
@@ -448,6 +449,17 @@
448
449
  "Strings",
449
450
  "Enumerations"
450
451
  ]
452
+ },
453
+ {
454
+ "slug": "clock",
455
+ "difficulty": 1,
456
+ "topics": [
457
+ "Protocols",
458
+ "Structs",
459
+ "Logic",
460
+ "Transforming",
461
+ "Integers"
462
+ ]
451
463
  }
452
464
  ],
453
465
  "deprecated": [
@@ -31,3 +31,84 @@ Or, you can enable all the tests by commenting out the
31
31
  ```elixir
32
32
  # ExUnit.configure exclude: :pending, trace: true
33
33
  ```
34
+
35
+ ### Typespecs and Dialyzer (DIscrepancy AnalYZer for ERlang programs)
36
+
37
+ Elixir exercises include a skeleton implementation file. This
38
+ file outlines the module and functions that you are expected
39
+ to implement. In most exercises, you will find typespecs
40
+ above the function declaration. These start with the `@spec` tag and
41
+ typically follow the `@spec function_name(type1, type2) :: return_type`
42
+ format. These are used in Elixir and Erlang as documentation and
43
+ in conjunction with a tool called Dialyzer to find type inconsistencies
44
+ and possible bugs. For more information see the
45
+ [Elixir typespecs guide](http://elixir-lang.org/getting-started/typespecs-and-behaviours.html)
46
+ or the [typespecs documentation](http://elixir-lang.org/docs/stable/elixir/typespecs.html). For
47
+ documentation about Dialyzer see [Erlang -- dialyzer](http://erlang.org/doc/man/dialyzer.html).
48
+
49
+ Optionally, you may want to check
50
+ the types of your implementation with Dialyzer. There are a couple
51
+ of steps you will need to take. Because all of the Elixir exercises
52
+ are implemented as `.exs` script files they will not create a
53
+ `.beam` file when they are dynamically compiled when running
54
+ normal tests. In order to create the `.beam` file that Dialyzer
55
+ needs to analyze run:
56
+
57
+ ```bash
58
+ $ elixirc word_count.exs
59
+ ```
60
+
61
+ This will create a file called `Elixir.Words.beam`. Now you can run
62
+ Dialyzer on your implementation with:
63
+
64
+ ```bash
65
+ $ dialyzer Elixir.Words.beam
66
+
67
+ Checking whether the PLT ~/.dialyzer_plt is up-to-date... yes
68
+ Proceeding with analysis...
69
+ done in 0m0.27s
70
+ done (passed successfully)
71
+ ```
72
+
73
+ If this is the first time you have run Dialyzer you
74
+ will most likely not have a `plt` file. The persistent lookup table,
75
+ or PLT is used by Dialyzer to cache information about built in Elixir
76
+ and Erlang types. To create a plt with sensible defaults run:
77
+
78
+
79
+ ```bash
80
+ $ dialyzer --build_plt --apps erts kernel stdlib crypto public_key /path/to/elixir
81
+ ```
82
+
83
+ Make sure to change the path to your system's path to the Elixir libraries. For
84
+ instance, if you installed Elixir with homebrew you will probably find it under
85
+ `/usr/local/Cellar/elixir/1.3.2`.
86
+
87
+ It should be reiterated that running Dialyzer and removing all warnings
88
+ is an optional step when completing an exercise. Dialyzer warnings can
89
+ be difficult to decipher. For instance, examine the warnings for this very silly
90
+ implementation of the `Bob` exercise.
91
+
92
+ ```elixir
93
+ defmodule Bob do
94
+ @spec hey(input :: String.t) :: String.t
95
+ def hey(input) do
96
+ 1
97
+ end
98
+
99
+ def hey(input) do
100
+ end
101
+ end
102
+ ```
103
+
104
+ This produces the following warnings.
105
+
106
+ ```bash
107
+ bob.exs:2: Invalid type specification for function 'Elixir.Bob':hey/1. The success typing is (_) -> 1
108
+ bob.exs:7: The variable _input@1 can never match since previous clauses completely covered the type any()
109
+ ```
110
+
111
+ The first warning means that the function is not returning
112
+ the correct type. The last indicates that the second function
113
+ definition can never be reached because the first function
114
+ definition always matches.
@@ -43,7 +43,7 @@ defmodule BankAccount do
43
43
  @doc """
44
44
  Close the bank. Makes the account unavailable.
45
45
  """
46
- @spec close_bank(account) :: none
46
+ @spec close_bank(account) :: any
47
47
  def close_bank(account) do
48
48
  :gen_server.call(account, :close)
49
49
  end
@@ -17,6 +17,11 @@ defmodule BinarySearchTest do
17
17
  assert BinarySearch.search({2, 4, 6}, 3) == :not_found
18
18
  end
19
19
 
20
+ @tag :pending
21
+ test "returns :not_found when key is too high" do
22
+ assert BinarySearch.search({2, 4, 6}, 9) == :not_found
23
+ end
24
+
20
25
  @tag :pending
21
26
  test "finds key in a tuple with a single item" do
22
27
  assert BinarySearch.search({3}, 3) == {:ok, 0}
@@ -0,0 +1,23 @@
1
+ defmodule Clock do
2
+ defstruct hour: 0, minute: 0
3
+
4
+ @doc """
5
+ Returns a string representation of a clock:
6
+
7
+ iex> Clock.new(8, 9) |> to_string
8
+ "08:09"
9
+ """
10
+ @spec new(integer, integer) :: Clock
11
+ def new(hour, minute) do
12
+ end
13
+
14
+ @doc """
15
+ Adds two clock times:
16
+
17
+ iex> Clock.add(10, 0) |> Clock.add(3) |> to_string
18
+ "10:03"
19
+ """
20
+ @spec add(Clock, integer) :: Clock
21
+ def add(%Clock{hour: hour, minute: minute}, add_minute) do
22
+ end
23
+ end