trackler 1.0.4.0 → 1.0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/common/CONTRIBUTING.md +17 -2
  3. data/common/exercises/anagram/canonical-data.json +0 -14
  4. data/common/exercises/pig-latin/canonical-data.json +6 -1
  5. data/common/exercises/raindrops/description.md +4 -4
  6. data/common/exercises/raindrops/metadata.yml +1 -1
  7. data/common/exercises/roman-numerals/metadata.yml +1 -1
  8. data/lib/trackler/version.rb +1 -1
  9. data/tracks/c/config.json +12 -1
  10. data/tracks/c/exercises/roman-numerals/makefile +16 -0
  11. data/tracks/c/exercises/roman-numerals/src/example.c +43 -0
  12. data/tracks/c/exercises/roman-numerals/src/example.h +6 -0
  13. data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +126 -0
  14. data/tracks/c/exercises/roman-numerals/test/vendor/unity.c +1300 -0
  15. data/tracks/c/exercises/roman-numerals/test/vendor/unity.h +274 -0
  16. data/tracks/c/exercises/roman-numerals/test/vendor/unity_internals.h +701 -0
  17. data/tracks/clojure/exercises/flatten-array/project.clj +4 -0
  18. data/tracks/csharp/exercises/protein-translation/ProteinTranslationTest.cs +1 -1
  19. data/tracks/elixir/exercises/bowling/bowling_test.exs +157 -62
  20. data/tracks/elixir/exercises/bowling/example.exs +33 -4
  21. data/tracks/erlang/config.json +176 -36
  22. data/tracks/go/.travis.yml +7 -1
  23. data/tracks/go/bin/test-without-stubs +29 -0
  24. data/tracks/go/exercises/robot-simulator/defs.go +1 -1
  25. data/tracks/go/exercises/variable-length-quantity/variable_length_quantity_test.go +31 -25
  26. data/tracks/haskell/.travis.yml +9 -5
  27. data/tracks/haskell/config.json +127 -121
  28. data/tracks/haskell/exercises/leap/src/LeapYear.hs +1 -1
  29. data/tracks/haskell/exercises/space-age/HINTS.md +14 -2
  30. data/tracks/haskell/exercises/space-age/{src/Example.hs → examples/success-double/SpaceAge.hs} +0 -0
  31. data/tracks/haskell/exercises/space-age/examples/success-double/package.yaml +19 -0
  32. data/tracks/haskell/exercises/space-age/examples/success-rational/SpaceAge.hs +24 -0
  33. data/tracks/haskell/exercises/space-age/examples/success-rational/package.yaml +19 -0
  34. data/tracks/haskell/exercises/space-age/src/SpaceAge.hs +4 -1
  35. data/tracks/haskell/exercises/space-age/test/Tests.hs +12 -5
  36. data/tracks/haskell/exercises/word-count/HINTS.md +21 -0
  37. data/tracks/haskell/exercises/word-count/examples/success-newtype/WordCount.hs +31 -0
  38. data/tracks/haskell/exercises/word-count/examples/success-newtype/package.yaml +21 -0
  39. data/tracks/haskell/exercises/word-count/examples/success-simple/WordCount.hs +13 -0
  40. data/tracks/haskell/exercises/word-count/examples/success-simple/package.yaml +20 -0
  41. data/tracks/haskell/exercises/word-count/package.yaml +0 -2
  42. data/tracks/haskell/exercises/word-count/src/WordCount.hs +2 -1
  43. data/tracks/haskell/exercises/word-count/test/Tests.hs +15 -6
  44. data/tracks/haskell/exercises/zebra-puzzle/package.yaml +19 -0
  45. data/tracks/haskell/exercises/zebra-puzzle/src/Example.hs +113 -0
  46. data/tracks/haskell/exercises/zebra-puzzle/src/ZebraPuzzle.hs +12 -0
  47. data/tracks/haskell/exercises/zebra-puzzle/stack.yaml +1 -0
  48. data/tracks/haskell/exercises/zebra-puzzle/test/Tests.hs +13 -0
  49. data/tracks/javascript/exercises/beer-song/beer-song.spec.js +5 -0
  50. data/tracks/lisp/config.json +147 -0
  51. data/tracks/ocaml/config.json +12 -0
  52. data/tracks/ocaml/exercises/atbash-cipher/.merlin +5 -0
  53. data/tracks/ocaml/exercises/atbash-cipher/HINTS.md +17 -0
  54. data/tracks/ocaml/exercises/atbash-cipher/Makefile +11 -0
  55. data/tracks/ocaml/exercises/atbash-cipher/atbash_cipher.mli +5 -0
  56. data/tracks/ocaml/exercises/atbash-cipher/example.ml +47 -0
  57. data/tracks/ocaml/exercises/atbash-cipher/test.ml +37 -0
  58. data/tracks/ocaml/exercises/meetup/.merlin +5 -0
  59. data/tracks/ocaml/exercises/meetup/Makefile +11 -0
  60. data/tracks/ocaml/exercises/meetup/example.ml +63 -0
  61. data/tracks/ocaml/exercises/meetup/meetup.mli +7 -0
  62. data/tracks/ocaml/exercises/meetup/test.ml +786 -0
  63. data/tracks/php/exercises/bowling/bowling_test.php +233 -10
  64. data/tracks/php/exercises/bowling/example.php +49 -6
  65. data/tracks/python/.travis.yml +5 -0
  66. data/tracks/python/config.json +33 -1
  67. data/tracks/python/exercises/flatten-array/example.py +18 -0
  68. data/tracks/python/exercises/flatten-array/flatten_array_test.py +40 -0
  69. data/tracks/python/exercises/robot-name/robot_name_test.py +8 -2
  70. data/tracks/r/config.json +32 -8
  71. data/tracks/ruby/bin/enable-executable +9 -5
  72. data/tracks/ruby/bin/executable-tests-check +7 -3
  73. data/tracks/ruby/bin/local-status-check +4 -4
  74. data/tracks/ruby/config.json +8 -1
  75. data/tracks/ruby/exercises/acronym/acronym_test.rb +0 -1
  76. data/tracks/ruby/exercises/anagram/.version +1 -0
  77. data/tracks/ruby/exercises/anagram/anagram_test.rb +101 -31
  78. data/tracks/ruby/exercises/anagram/example.rb +4 -0
  79. data/tracks/ruby/exercises/anagram/example.tt +19 -0
  80. data/tracks/ruby/exercises/gigasecond/.version +1 -1
  81. data/tracks/ruby/exercises/gigasecond/example.rb +1 -1
  82. data/tracks/ruby/exercises/gigasecond/gigasecond_test.rb +2 -2
  83. data/tracks/ruby/exercises/isogram/.version +1 -0
  84. data/tracks/ruby/exercises/isogram/example.rb +10 -0
  85. data/tracks/ruby/exercises/isogram/example.tt +20 -0
  86. data/tracks/ruby/exercises/isogram/isogram_test.rb +90 -0
  87. data/tracks/ruby/exercises/poker/example.rb +97 -39
  88. data/tracks/ruby/exercises/poker/poker_test.rb +67 -36
  89. data/tracks/ruby/exercises/sieve/.version +1 -0
  90. data/tracks/ruby/exercises/sieve/example.rb +4 -0
  91. data/tracks/ruby/exercises/sieve/example.tt +21 -0
  92. data/tracks/ruby/exercises/sieve/sieve_test.rb +36 -13
  93. data/tracks/ruby/exercises/word-count/example.tt +4 -3
  94. data/tracks/ruby/exercises/word-count/word_count_test.rb +38 -48
  95. data/tracks/ruby/lib/anagram_cases.rb +42 -0
  96. data/tracks/ruby/lib/isogram_cases.rb +24 -0
  97. data/tracks/ruby/lib/sieve_cases.rb +33 -0
  98. data/tracks/ruby/lib/word_count_cases.rb +19 -0
  99. data/tracks/scala/config.json +21 -0
  100. data/tracks/scala/docs/RESOURCES.md +1 -0
  101. data/tracks/scala/exercises/bracket-push/build.sbt +4 -0
  102. data/tracks/scala/exercises/bracket-push/example.scala +23 -0
  103. data/tracks/scala/exercises/bracket-push/src/main/scala/.keep +0 -0
  104. data/tracks/scala/exercises/bracket-push/src/test/scala/BracketsTest.scala +68 -0
  105. data/tracks/scala/exercises/change/src/test/scala/ChangeTest.scala +7 -0
  106. data/tracks/scala/exercises/sgf-parsing/build.sbt +7 -0
  107. data/tracks/scala/exercises/sgf-parsing/example.scala +66 -0
  108. data/tracks/scala/exercises/sgf-parsing/src/main/scala/.keep +0 -0
  109. data/tracks/scala/exercises/sgf-parsing/src/main/scala/Sgf.scala +17 -0
  110. data/tracks/scala/exercises/sgf-parsing/src/test/scala/SgfTest.scala +66 -0
  111. data/tracks/scala/exercises/zebra-puzzle/build.sbt +3 -0
  112. data/tracks/scala/exercises/zebra-puzzle/example.scala +152 -0
  113. data/tracks/scala/exercises/zebra-puzzle/src/main/scala/.keep +0 -0
  114. data/tracks/scala/exercises/zebra-puzzle/src/main/scala/ZebraPuzzle.scala +14 -0
  115. data/tracks/scala/exercises/zebra-puzzle/src/test/scala/ZebraPuzzleTest.scala +11 -0
  116. data/tracks/scala/testgen/src/main/scala/BracketPushTestGenerator.scala +44 -0
  117. metadata +63 -3
  118. data/tracks/haskell/exercises/word-count/src/Example.hs +0 -8
@@ -0,0 +1 @@
1
+ resolver: nightly-2016-07-17
@@ -0,0 +1,13 @@
1
+ import Test.Hspec (Spec, describe, it, shouldBe)
2
+ import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)
3
+
4
+ import ZebraPuzzle (Resident(..), Solution(..), solve)
5
+
6
+ main :: IO ()
7
+ main = hspecWith defaultConfig {configFastFail = True} specs
8
+
9
+ specs :: Spec
10
+ specs = describe "zebra-puzzle" $
11
+ it "solve" $ solve `shouldBe` Solution { waterDrinker = Norwegian
12
+ , zebraOwner = Japanese }
13
+
@@ -8,6 +8,11 @@ describe('BeerSong', function() {
8
8
  expect(song.verse(8)).toEqual(expected);
9
9
  });
10
10
 
11
+ xit('handles 2 bottles', function() {
12
+ var expected = '2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n';
13
+ expect(song.verse(2)).toEqual(expected);
14
+ });
15
+
11
16
  xit('handles 1 bottle', function() {
12
17
  var expected = '1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n';
13
18
  expect(song.verse(1)).toEqual(expected);
@@ -34,6 +34,153 @@
34
34
  "crypto-square",
35
35
  "trinary"
36
36
  ],
37
+ "exercises": [
38
+ {
39
+ "slug": "hamming",
40
+ "difficulty": 1,
41
+ "topics": []
42
+ },
43
+ {
44
+ "slug": "leap",
45
+ "difficulty": 1,
46
+ "topics": []
47
+ },
48
+ {
49
+ "slug": "grains",
50
+ "difficulty": 1,
51
+ "topics": []
52
+ },
53
+ {
54
+ "slug": "gigasecond",
55
+ "difficulty": 1,
56
+ "topics": []
57
+ },
58
+ {
59
+ "slug": "bob",
60
+ "difficulty": 1,
61
+ "topics": []
62
+ },
63
+ {
64
+ "slug": "rna-transcription",
65
+ "difficulty": 1,
66
+ "topics": []
67
+ },
68
+ {
69
+ "slug": "robot-name",
70
+ "difficulty": 1,
71
+ "topics": []
72
+ },
73
+ {
74
+ "slug": "word-count",
75
+ "difficulty": 1,
76
+ "topics": []
77
+ },
78
+ {
79
+ "slug": "raindrops",
80
+ "difficulty": 1,
81
+ "topics": []
82
+ },
83
+ {
84
+ "slug": "grade-school",
85
+ "difficulty": 1,
86
+ "topics": []
87
+ },
88
+ {
89
+ "slug": "phone-number",
90
+ "difficulty": 1,
91
+ "topics": []
92
+ },
93
+ {
94
+ "slug": "etl",
95
+ "difficulty": 1,
96
+ "topics": []
97
+ },
98
+ {
99
+ "slug": "beer-song",
100
+ "difficulty": 1,
101
+ "topics": []
102
+ },
103
+ {
104
+ "slug": "space-age",
105
+ "difficulty": 1,
106
+ "topics": []
107
+ },
108
+ {
109
+ "slug": "anagram",
110
+ "difficulty": 1,
111
+ "topics": []
112
+ },
113
+ {
114
+ "slug": "nucleotide-count",
115
+ "difficulty": 1,
116
+ "topics": []
117
+ },
118
+ {
119
+ "slug": "meetup",
120
+ "difficulty": 1,
121
+ "topics": []
122
+ },
123
+ {
124
+ "slug": "triangle",
125
+ "difficulty": 1,
126
+ "topics": []
127
+ },
128
+ {
129
+ "slug": "difference-of-squares",
130
+ "difficulty": 1,
131
+ "topics": []
132
+ },
133
+ {
134
+ "slug": "roman-numerals",
135
+ "difficulty": 1,
136
+ "topics": []
137
+ },
138
+ {
139
+ "slug": "scrabble-score",
140
+ "difficulty": 1,
141
+ "topics": []
142
+ },
143
+ {
144
+ "slug": "binary",
145
+ "difficulty": 1,
146
+ "topics": []
147
+ },
148
+ {
149
+ "slug": "allergies",
150
+ "difficulty": 1,
151
+ "topics": []
152
+ },
153
+ {
154
+ "slug": "sieve",
155
+ "difficulty": 1,
156
+ "topics": []
157
+ },
158
+ {
159
+ "slug": "strain",
160
+ "difficulty": 1,
161
+ "topics": []
162
+ },
163
+ {
164
+ "slug": "atbash-cipher",
165
+ "difficulty": 1,
166
+ "topics": []
167
+ },
168
+ {
169
+ "slug": "prime-factors",
170
+ "difficulty": 1,
171
+ "topics": []
172
+ },
173
+ {
174
+ "slug": "crypto-square",
175
+ "difficulty": 1,
176
+ "topics": []
177
+ },
178
+ {
179
+ "slug": "trinary",
180
+ "difficulty": 1,
181
+ "topics": []
182
+ }
183
+ ],
37
184
  "deprecated": [
38
185
 
39
186
  ],
@@ -26,8 +26,10 @@
26
26
  "prime-factors",
27
27
  "etl",
28
28
  "hexadecimal",
29
+ "atbash-cipher",
29
30
  "luhn",
30
31
  "say",
32
+ "meetup",
31
33
  "zipper",
32
34
  "hangman"
33
35
  ],
@@ -142,6 +144,11 @@
142
144
  "difficulty": 1,
143
145
  "topics": []
144
146
  },
147
+ {
148
+ "slug": "atbash-cipher",
149
+ "difficulty": 1,
150
+ "topics": []
151
+ },
145
152
  {
146
153
  "slug": "luhn",
147
154
  "difficulty": 1,
@@ -152,6 +159,11 @@
152
159
  "difficulty": 1,
153
160
  "topics": []
154
161
  },
162
+ {
163
+ "slug": "meetup",
164
+ "difficulty": 1,
165
+ "topics": ["Dates"]
166
+ },
155
167
  {
156
168
  "slug": "zipper",
157
169
  "difficulty": 1,
@@ -0,0 +1,5 @@
1
+ PKG findlib
2
+ PKG core
3
+ PKG ounit
4
+ S *
5
+ B *
@@ -0,0 +1,17 @@
1
+ ## Deprecation of String.lowercase
2
+ Depending on the version of OCaml you installed the use of `String.lowercase` is
3
+ frowned upon. Since version 4.03.0 `String.lowercase` is deprecated in favor of
4
+ `String.lowercase_ascii`. So instead of writing
5
+
6
+ ```ocaml
7
+ String.lowercase "Hello, World!"
8
+ ```
9
+
10
+ use
11
+
12
+ ```ocaml
13
+ String.lowercase_ascii "Hello, World!"
14
+ ```
15
+
16
+ See [String documentation](http://caml.inria.fr/pub/docs/manual-ocaml/libref/String.html)
17
+ for more useful functions.
@@ -0,0 +1,11 @@
1
+ test: test.native
2
+ @./test.native
3
+
4
+ test.native: *.ml *.mli
5
+ @corebuild -r -quiet -pkg oUnit test.native
6
+
7
+ clean:
8
+ rm -rf _build
9
+ rm -f test.native
10
+
11
+ .PHONY: clean
@@ -0,0 +1,5 @@
1
+ (* Encoding from English to atbash cipher. The default for block_size is 5 *)
2
+ val encode : ?block_size:int -> string -> string
3
+
4
+ (* Decoding from atbash to English *)
5
+ val decode : string -> string
@@ -0,0 +1,47 @@
1
+ open Core.Std
2
+
3
+ let substitute = function
4
+ | 'a' .. 'z' as c ->
5
+ let offset = (Char.to_int c) - (Char.to_int 'a') in
6
+ let code = (Char.to_int 'z') - offset in
7
+ Char.of_int_exn code
8
+ | other -> other
9
+
10
+ let is_encodable = function
11
+ | 'a' .. 'z' | '0' .. '9' -> true
12
+ | _ -> false
13
+
14
+ let explode s =
15
+ let rec expl i l =
16
+ if i < 0 then
17
+ l
18
+ else
19
+ expl (i - 1) (s.[i] :: l)
20
+ in
21
+ expl ((String.length s) - 1) []
22
+
23
+ let implode l =
24
+ let character_at i = List.nth_exn l i in
25
+ String.init (List.length l) character_at
26
+
27
+ let rec group n l =
28
+ if (List.length l) <= n then
29
+ [l]
30
+ else
31
+ (List.take l n) :: (group n (List.drop l n))
32
+
33
+ let encode ?block_size:(block_size = 5) text =
34
+ let lowercase_text = String.lowercase text in
35
+ let characters = explode lowercase_text in
36
+ let filtered_characters = List.filter ~f:is_encodable characters in
37
+ let groups = group block_size filtered_characters in
38
+ let preprocessed_texts = List.map ~f:implode groups in
39
+ let texts = List.map ~f:(String.map ~f:substitute) preprocessed_texts in
40
+ String.concat ~sep:" " texts
41
+
42
+ let decode text =
43
+ let lowercase_text = String.lowercase text in
44
+ let characters = explode lowercase_text in
45
+ let filtered_characters = List.filter ~f:is_encodable characters in
46
+ let preprocessed_text = implode filtered_characters in
47
+ String.map ~f:substitute preprocessed_text
@@ -0,0 +1,37 @@
1
+ open Core.Std
2
+ open OUnit2
3
+ open Atbash_cipher
4
+
5
+ let ae exp got _test_ctxt = assert_equal ~printer:String.to_string exp got
6
+
7
+ let tests =
8
+ ["encode yes">::
9
+ ae "bvh" (encode "yes");
10
+ "encode no">::
11
+ ae "ml" (encode "no");
12
+ "encode OMG">::
13
+ ae "lnt" (encode "OMG");
14
+ "encode spaces">::
15
+ ae "lnt" (encode "O M G");
16
+ "encode mindblowingly">::
17
+ ae "nrmwy oldrm tob" (encode "mindblowingly");
18
+ "encode numbers">::
19
+ ae "gvhgr mt123 gvhgr mt" (encode "Testing,1 2 3, testing.");
20
+ "encode deep thought">::
21
+ ae "gifgs rhurx grlm" (encode "Truth is fiction.");
22
+ "encode all the letters">::
23
+ ae "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt" (encode "The quick brown fox jumps over the lazy dog.");
24
+ "encode ignores non ascii">::
25
+ ae "mlmzh xrrrt mlivw" (encode "non ascii éignored");
26
+ "encode mindblowingly with a different block size">::
27
+ ae "n r m w y o l d r m t o b" (encode ~block_size:1 "mindblowingly");
28
+ "decode exercism">::
29
+ ae "exercism" (decode "vcvix rhn");
30
+ "decode a sentence">::
31
+ ae "anobstacleisoftenasteppingstone" (decode "zmlyh gzxov rhlug vmzhg vkkrm thglm v");
32
+ "decode all the letters">::
33
+ ae "thequickbrownfoxjumpsoverthelazydog" (decode "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt");
34
+ ]
35
+
36
+ let () =
37
+ run_test_tt_main ("atbash cipher" >::: tests)
@@ -0,0 +1,5 @@
1
+ PKG findlib
2
+ PKG core
3
+ PKG ounit
4
+ S *
5
+ B *
@@ -0,0 +1,11 @@
1
+ test: test.native
2
+ @./test.native
3
+
4
+ test.native: *.ml *.mli
5
+ @corebuild -r -quiet -pkg oUnit test.native
6
+
7
+ clean:
8
+ rm -rf _build
9
+ rm -f test.native
10
+
11
+ .PHONY: clean
@@ -0,0 +1,63 @@
1
+ open Core.Std
2
+
3
+ type schedule = First | Second | Third | Fourth | Teenth | Last
4
+
5
+ type weekday = Monday | Tuesday | Wednesday | Thursday
6
+ | Friday | Saturday | Sunday
7
+
8
+ type date = (int * int * int)
9
+
10
+ let diff_days (d1: weekday) (d2: weekday): int =
11
+ let weekday_to_int = function
12
+ | Monday -> 0
13
+ | Tuesday -> 1
14
+ | Wednesday -> 2
15
+ | Thursday -> 3
16
+ | Friday -> 4
17
+ | Saturday -> 5
18
+ | Sunday -> 6 in
19
+ (weekday_to_int d1 - weekday_to_int d2) % 7
20
+
21
+ let day_of_week (d: Date.t): weekday = let open Day_of_week in
22
+ match Date.day_of_week d with
23
+ | Sun -> Sunday
24
+ | Mon -> Monday
25
+ | Tue -> Tuesday
26
+ | Wed -> Wednesday
27
+ | Thu -> Thursday
28
+ | Fri -> Friday
29
+ | Sat -> Saturday
30
+
31
+ let schedule_to_int = function
32
+ | First -> 0
33
+ | Second -> 1
34
+ | Third -> 2
35
+ | Fourth -> 3
36
+ | Teenth -> 4
37
+ | Last -> 5
38
+
39
+ let is_leap_year y =
40
+ let divides n = y % n = 0 in
41
+ divides 4 && (not @@ divides 100 || divides 400)
42
+
43
+ let month_length y = let open Month in function
44
+ | Feb -> if is_leap_year y then 29 else 28
45
+ | Apr -> 30
46
+ | Jun -> 30
47
+ | Sep -> 30
48
+ | Nov -> 30
49
+ | _ -> 31
50
+
51
+ let meetup_day schedule weekday ~year ~month =
52
+ let month = Month.of_int_exn month in
53
+ let base = Date.create_exn ~y:year ~m:month ~d:1 in
54
+ let calc_offset start = start + diff_days weekday
55
+ (Date.add_days base start |> day_of_week) in
56
+ let day = calc_offset @@ match schedule with
57
+ | Teenth -> 12
58
+ | Last -> 21 + max 0 (month_length year month - 28)
59
+ | _ -> 7 * schedule_to_int schedule in
60
+ let core_date = Date.add_days base day
61
+ in (Date.year core_date,
62
+ Date.month core_date |> Month.to_int,
63
+ Date.day core_date)
@@ -0,0 +1,7 @@
1
+ type schedule = First | Second | Third | Fourth | Teenth | Last
2
+
3
+ type weekday = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
4
+
5
+ type date = (int * int * int)
6
+
7
+ val meetup_day : schedule -> weekday -> year:int -> month:int -> date
@@ -0,0 +1,786 @@
1
+ open OUnit2
2
+ open Meetup
3
+ open Core.Std
4
+
5
+ type case = {
6
+ description: string;
7
+ year: int;
8
+ month: int;
9
+ week: schedule;
10
+ dayofweek: weekday;
11
+ dayofmonth: int
12
+ }
13
+
14
+ let ae exp got _test_ctxt = assert_equal
15
+ ~printer:(fun (y, m, d) -> sprintf "%d-%02d-%02d" y m d) exp got
16
+
17
+ let make_test (c: case) =
18
+ c.description >::
19
+ ae (c.year, c.month, c.dayofmonth)
20
+ (meetup_day c.week c.dayofweek ~year:c.year ~month:c.month)
21
+
22
+ let tests = List.map ~f:make_test [
23
+ {
24
+ description = "monteenth of May 2013";
25
+ year = 2013;
26
+ month = 5;
27
+ week = Teenth;
28
+ dayofweek = Monday;
29
+ dayofmonth = 13
30
+ };
31
+ {
32
+ description = "monteenth of August 2013";
33
+ year = 2013;
34
+ month = 8;
35
+ week = Teenth;
36
+ dayofweek = Monday;
37
+ dayofmonth = 19
38
+ };
39
+ {
40
+ description = "monteenth of September 2013";
41
+ year = 2013;
42
+ month = 9;
43
+ week = Teenth;
44
+ dayofweek = Monday;
45
+ dayofmonth = 16
46
+ };
47
+ {
48
+ description = "tuesteenth of March 2013";
49
+ year = 2013;
50
+ month = 3;
51
+ week = Teenth;
52
+ dayofweek = Tuesday;
53
+ dayofmonth = 19
54
+ };
55
+ {
56
+ description = "tuesteenth of April 2013";
57
+ year = 2013;
58
+ month = 4;
59
+ week = Teenth;
60
+ dayofweek = Tuesday;
61
+ dayofmonth = 16
62
+ };
63
+ {
64
+ description = "tuesteenth of August 2013";
65
+ year = 2013;
66
+ month = 8;
67
+ week = Teenth;
68
+ dayofweek = Tuesday;
69
+ dayofmonth = 13
70
+ };
71
+ {
72
+ description = "wednesteenth of January 2013";
73
+ year = 2013;
74
+ month = 1;
75
+ week = Teenth;
76
+ dayofweek = Wednesday;
77
+ dayofmonth = 16
78
+ };
79
+ {
80
+ description = "wednesteenth of February 2013";
81
+ year = 2013;
82
+ month = 2;
83
+ week = Teenth;
84
+ dayofweek = Wednesday;
85
+ dayofmonth = 13
86
+ };
87
+ {
88
+ description = "wednesteenth of June 2013";
89
+ year = 2013;
90
+ month = 6;
91
+ week = Teenth;
92
+ dayofweek = Wednesday;
93
+ dayofmonth = 19
94
+ };
95
+ {
96
+ description = "thursteenth of May 2013";
97
+ year = 2013;
98
+ month = 5;
99
+ week = Teenth;
100
+ dayofweek = Thursday;
101
+ dayofmonth = 16
102
+ };
103
+ {
104
+ description = "thursteenth of June 2013";
105
+ year = 2013;
106
+ month = 6;
107
+ week = Teenth;
108
+ dayofweek = Thursday;
109
+ dayofmonth = 13
110
+ };
111
+ {
112
+ description = "thursteenth of September 2013";
113
+ year = 2013;
114
+ month = 9;
115
+ week = Teenth;
116
+ dayofweek = Thursday;
117
+ dayofmonth = 19
118
+ };
119
+ {
120
+ description = "friteenth of April 2013";
121
+ year = 2013;
122
+ month = 4;
123
+ week = Teenth;
124
+ dayofweek = Friday;
125
+ dayofmonth = 19
126
+ };
127
+ {
128
+ description = "friteenth of August 2013";
129
+ year = 2013;
130
+ month = 8;
131
+ week = Teenth;
132
+ dayofweek = Friday;
133
+ dayofmonth = 16
134
+ };
135
+ {
136
+ description = "friteenth of September 2013";
137
+ year = 2013;
138
+ month = 9;
139
+ week = Teenth;
140
+ dayofweek = Friday;
141
+ dayofmonth = 13
142
+ };
143
+ {
144
+ description = "saturteenth of February 2013";
145
+ year = 2013;
146
+ month = 2;
147
+ week = Teenth;
148
+ dayofweek = Saturday;
149
+ dayofmonth = 16
150
+ };
151
+ {
152
+ description = "saturteenth of April 2013";
153
+ year = 2013;
154
+ month = 4;
155
+ week = Teenth;
156
+ dayofweek = Saturday;
157
+ dayofmonth = 13
158
+ };
159
+ {
160
+ description = "saturteenth of October 2013";
161
+ year = 2013;
162
+ month = 10;
163
+ week = Teenth;
164
+ dayofweek = Saturday;
165
+ dayofmonth = 19
166
+ };
167
+ {
168
+ description = "sunteenth of May 2013";
169
+ year = 2013;
170
+ month = 5;
171
+ week = Teenth;
172
+ dayofweek = Sunday;
173
+ dayofmonth = 19
174
+ };
175
+ {
176
+ description = "sunteenth of June 2013";
177
+ year = 2013;
178
+ month = 6;
179
+ week = Teenth;
180
+ dayofweek = Sunday;
181
+ dayofmonth = 16
182
+ };
183
+ {
184
+ description = "sunteenth of October 2013";
185
+ year = 2013;
186
+ month = 10;
187
+ week = Teenth;
188
+ dayofweek = Sunday;
189
+ dayofmonth = 13
190
+ };
191
+ {
192
+ description = "first Monday of March 2013";
193
+ year = 2013;
194
+ month = 3;
195
+ week = First;
196
+ dayofweek = Monday;
197
+ dayofmonth = 4
198
+ };
199
+ {
200
+ description = "first Monday of April 2013";
201
+ year = 2013;
202
+ month = 4;
203
+ week = First;
204
+ dayofweek = Monday;
205
+ dayofmonth = 1
206
+ };
207
+ {
208
+ description = "first Tuesday of May 2013";
209
+ year = 2013;
210
+ month = 5;
211
+ week = First;
212
+ dayofweek = Tuesday;
213
+ dayofmonth = 7
214
+ };
215
+ {
216
+ description = "first Tuesday of June 2013";
217
+ year = 2013;
218
+ month = 6;
219
+ week = First;
220
+ dayofweek = Tuesday;
221
+ dayofmonth = 4
222
+ };
223
+ {
224
+ description = "first Wednesday of July 2013";
225
+ year = 2013;
226
+ month = 7;
227
+ week = First;
228
+ dayofweek = Wednesday;
229
+ dayofmonth = 3
230
+ };
231
+ {
232
+ description = "first Wednesday of August 2013";
233
+ year = 2013;
234
+ month = 8;
235
+ week = First;
236
+ dayofweek = Wednesday;
237
+ dayofmonth = 7
238
+ };
239
+ {
240
+ description = "first Thursday of September 2013";
241
+ year = 2013;
242
+ month = 9;
243
+ week = First;
244
+ dayofweek = Thursday;
245
+ dayofmonth = 5
246
+ };
247
+ {
248
+ description = "first Thursday of October 2013";
249
+ year = 2013;
250
+ month = 10;
251
+ week = First;
252
+ dayofweek = Thursday;
253
+ dayofmonth = 3
254
+ };
255
+ {
256
+ description = "first Friday of November 2013";
257
+ year = 2013;
258
+ month = 11;
259
+ week = First;
260
+ dayofweek = Friday;
261
+ dayofmonth = 1
262
+ };
263
+ {
264
+ description = "first Friday of December 2013";
265
+ year = 2013;
266
+ month = 12;
267
+ week = First;
268
+ dayofweek = Friday;
269
+ dayofmonth = 6
270
+ };
271
+ {
272
+ description = "first Saturday of January 2013";
273
+ year = 2013;
274
+ month = 1;
275
+ week = First;
276
+ dayofweek = Saturday;
277
+ dayofmonth = 5
278
+ };
279
+ {
280
+ description = "first Saturday of February 2013";
281
+ year = 2013;
282
+ month = 2;
283
+ week = First;
284
+ dayofweek = Saturday;
285
+ dayofmonth = 2
286
+ };
287
+ {
288
+ description = "first Sunday of March 2013";
289
+ year = 2013;
290
+ month = 3;
291
+ week = First;
292
+ dayofweek = Sunday;
293
+ dayofmonth = 3
294
+ };
295
+ {
296
+ description = "first Sunday of April 2013";
297
+ year = 2013;
298
+ month = 4;
299
+ week = First;
300
+ dayofweek = Sunday;
301
+ dayofmonth = 7
302
+ };
303
+ {
304
+ description = "second Monday of March 2013";
305
+ year = 2013;
306
+ month = 3;
307
+ week = Second;
308
+ dayofweek = Monday;
309
+ dayofmonth = 11
310
+ };
311
+ {
312
+ description = "second Monday of April 2013";
313
+ year = 2013;
314
+ month = 4;
315
+ week = Second;
316
+ dayofweek = Monday;
317
+ dayofmonth = 8
318
+ };
319
+ {
320
+ description = "second Tuesday of May 2013";
321
+ year = 2013;
322
+ month = 5;
323
+ week = Second;
324
+ dayofweek = Tuesday;
325
+ dayofmonth = 14
326
+ };
327
+ {
328
+ description = "second Tuesday of June 2013";
329
+ year = 2013;
330
+ month = 6;
331
+ week = Second;
332
+ dayofweek = Tuesday;
333
+ dayofmonth = 11
334
+ };
335
+ {
336
+ description = "second Wednesday of July 2013";
337
+ year = 2013;
338
+ month = 7;
339
+ week = Second;
340
+ dayofweek = Wednesday;
341
+ dayofmonth = 10
342
+ };
343
+ {
344
+ description = "second Wednesday of August 2013";
345
+ year = 2013;
346
+ month = 8;
347
+ week = Second;
348
+ dayofweek = Wednesday;
349
+ dayofmonth = 14
350
+ };
351
+ {
352
+ description = "second Thursday of September 2013";
353
+ year = 2013;
354
+ month = 9;
355
+ week = Second;
356
+ dayofweek = Thursday;
357
+ dayofmonth = 12
358
+ };
359
+ {
360
+ description = "second Thursday of October 2013";
361
+ year = 2013;
362
+ month = 10;
363
+ week = Second;
364
+ dayofweek = Thursday;
365
+ dayofmonth = 10
366
+ };
367
+ {
368
+ description = "second Friday of November 2013";
369
+ year = 2013;
370
+ month = 11;
371
+ week = Second;
372
+ dayofweek = Friday;
373
+ dayofmonth = 8
374
+ };
375
+ {
376
+ description = "second Friday of December 2013";
377
+ year = 2013;
378
+ month = 12;
379
+ week = Second;
380
+ dayofweek = Friday;
381
+ dayofmonth = 13
382
+ };
383
+ {
384
+ description = "second Saturday of January 2013";
385
+ year = 2013;
386
+ month = 1;
387
+ week = Second;
388
+ dayofweek = Saturday;
389
+ dayofmonth = 12
390
+ };
391
+ {
392
+ description = "second Saturday of February 2013";
393
+ year = 2013;
394
+ month = 2;
395
+ week = Second;
396
+ dayofweek = Saturday;
397
+ dayofmonth = 9
398
+ };
399
+ {
400
+ description = "second Sunday of March 2013";
401
+ year = 2013;
402
+ month = 3;
403
+ week = Second;
404
+ dayofweek = Sunday;
405
+ dayofmonth = 10
406
+ };
407
+ {
408
+ description = "second Sunday of April 2013";
409
+ year = 2013;
410
+ month = 4;
411
+ week = Second;
412
+ dayofweek = Sunday;
413
+ dayofmonth = 14
414
+ };
415
+ {
416
+ description = "third Monday of March 2013";
417
+ year = 2013;
418
+ month = 3;
419
+ week = Third;
420
+ dayofweek = Monday;
421
+ dayofmonth = 18
422
+ };
423
+ {
424
+ description = "third Monday of April 2013";
425
+ year = 2013;
426
+ month = 4;
427
+ week = Third;
428
+ dayofweek = Monday;
429
+ dayofmonth = 15
430
+ };
431
+ {
432
+ description = "third Tuesday of May 2013";
433
+ year = 2013;
434
+ month = 5;
435
+ week = Third;
436
+ dayofweek = Tuesday;
437
+ dayofmonth = 21
438
+ };
439
+ {
440
+ description = "third Tuesday of June 2013";
441
+ year = 2013;
442
+ month = 6;
443
+ week = Third;
444
+ dayofweek = Tuesday;
445
+ dayofmonth = 18
446
+ };
447
+ {
448
+ description = "third Wednesday of July 2013";
449
+ year = 2013;
450
+ month = 7;
451
+ week = Third;
452
+ dayofweek = Wednesday;
453
+ dayofmonth = 17
454
+ };
455
+ {
456
+ description = "third Wednesday of August 2013";
457
+ year = 2013;
458
+ month = 8;
459
+ week = Third;
460
+ dayofweek = Wednesday;
461
+ dayofmonth = 21
462
+ };
463
+ {
464
+ description = "third Thursday of September 2013";
465
+ year = 2013;
466
+ month = 9;
467
+ week = Third;
468
+ dayofweek = Thursday;
469
+ dayofmonth = 19
470
+ };
471
+ {
472
+ description = "third Thursday of October 2013";
473
+ year = 2013;
474
+ month = 10;
475
+ week = Third;
476
+ dayofweek = Thursday;
477
+ dayofmonth = 17
478
+ };
479
+ {
480
+ description = "third Friday of November 2013";
481
+ year = 2013;
482
+ month = 11;
483
+ week = Third;
484
+ dayofweek = Friday;
485
+ dayofmonth = 15
486
+ };
487
+ {
488
+ description = "third Friday of December 2013";
489
+ year = 2013;
490
+ month = 12;
491
+ week = Third;
492
+ dayofweek = Friday;
493
+ dayofmonth = 20
494
+ };
495
+ {
496
+ description = "third Saturday of January 2013";
497
+ year = 2013;
498
+ month = 1;
499
+ week = Third;
500
+ dayofweek = Saturday;
501
+ dayofmonth = 19
502
+ };
503
+ {
504
+ description = "third Saturday of February 2013";
505
+ year = 2013;
506
+ month = 2;
507
+ week = Third;
508
+ dayofweek = Saturday;
509
+ dayofmonth = 16
510
+ };
511
+ {
512
+ description = "third Sunday of March 2013";
513
+ year = 2013;
514
+ month = 3;
515
+ week = Third;
516
+ dayofweek = Sunday;
517
+ dayofmonth = 17
518
+ };
519
+ {
520
+ description = "third Sunday of April 2013";
521
+ year = 2013;
522
+ month = 4;
523
+ week = Third;
524
+ dayofweek = Sunday;
525
+ dayofmonth = 21
526
+ };
527
+ {
528
+ description = "fourth Monday of March 2013";
529
+ year = 2013;
530
+ month = 3;
531
+ week = Fourth;
532
+ dayofweek = Monday;
533
+ dayofmonth = 25
534
+ };
535
+ {
536
+ description = "fourth Monday of April 2013";
537
+ year = 2013;
538
+ month = 4;
539
+ week = Fourth;
540
+ dayofweek = Monday;
541
+ dayofmonth = 22
542
+ };
543
+ {
544
+ description = "fourth Tuesday of May 2013";
545
+ year = 2013;
546
+ month = 5;
547
+ week = Fourth;
548
+ dayofweek = Tuesday;
549
+ dayofmonth = 28
550
+ };
551
+ {
552
+ description = "fourth Tuesday of June 2013";
553
+ year = 2013;
554
+ month = 6;
555
+ week = Fourth;
556
+ dayofweek = Tuesday;
557
+ dayofmonth = 25
558
+ };
559
+ {
560
+ description = "fourth Wednesday of July 2013";
561
+ year = 2013;
562
+ month = 7;
563
+ week = Fourth;
564
+ dayofweek = Wednesday;
565
+ dayofmonth = 24
566
+ };
567
+ {
568
+ description = "fourth Wednesday of August 2013";
569
+ year = 2013;
570
+ month = 8;
571
+ week = Fourth;
572
+ dayofweek = Wednesday;
573
+ dayofmonth = 28
574
+ };
575
+ {
576
+ description = "fourth Thursday of September 2013";
577
+ year = 2013;
578
+ month = 9;
579
+ week = Fourth;
580
+ dayofweek = Thursday;
581
+ dayofmonth = 26
582
+ };
583
+ {
584
+ description = "fourth Thursday of October 2013";
585
+ year = 2013;
586
+ month = 10;
587
+ week = Fourth;
588
+ dayofweek = Thursday;
589
+ dayofmonth = 24
590
+ };
591
+ {
592
+ description = "fourth Friday of November 2013";
593
+ year = 2013;
594
+ month = 11;
595
+ week = Fourth;
596
+ dayofweek = Friday;
597
+ dayofmonth = 22
598
+ };
599
+ {
600
+ description = "fourth Friday of December 2013";
601
+ year = 2013;
602
+ month = 12;
603
+ week = Fourth;
604
+ dayofweek = Friday;
605
+ dayofmonth = 27
606
+ };
607
+ {
608
+ description = "fourth Saturday of January 2013";
609
+ year = 2013;
610
+ month = 1;
611
+ week = Fourth;
612
+ dayofweek = Saturday;
613
+ dayofmonth = 26
614
+ };
615
+ {
616
+ description = "fourth Saturday of February 2013";
617
+ year = 2013;
618
+ month = 2;
619
+ week = Fourth;
620
+ dayofweek = Saturday;
621
+ dayofmonth = 23
622
+ };
623
+ {
624
+ description = "fourth Sunday of March 2013";
625
+ year = 2013;
626
+ month = 3;
627
+ week = Fourth;
628
+ dayofweek = Sunday;
629
+ dayofmonth = 24
630
+ };
631
+ {
632
+ description = "fourth Sunday of April 2013";
633
+ year = 2013;
634
+ month = 4;
635
+ week = Fourth;
636
+ dayofweek = Sunday;
637
+ dayofmonth = 28
638
+ };
639
+ {
640
+ description = "last Monday of March 2013";
641
+ year = 2013;
642
+ month = 3;
643
+ week = Last;
644
+ dayofweek = Monday;
645
+ dayofmonth = 25
646
+ };
647
+ {
648
+ description = "last Monday of April 2013";
649
+ year = 2013;
650
+ month = 4;
651
+ week = Last;
652
+ dayofweek = Monday;
653
+ dayofmonth = 29
654
+ };
655
+ {
656
+ description = "last Tuesday of May 2013";
657
+ year = 2013;
658
+ month = 5;
659
+ week = Last;
660
+ dayofweek = Tuesday;
661
+ dayofmonth = 28
662
+ };
663
+ {
664
+ description = "last Tuesday of June 2013";
665
+ year = 2013;
666
+ month = 6;
667
+ week = Last;
668
+ dayofweek = Tuesday;
669
+ dayofmonth = 25
670
+ };
671
+ {
672
+ description = "last Wednesday of July 2013";
673
+ year = 2013;
674
+ month = 7;
675
+ week = Last;
676
+ dayofweek = Wednesday;
677
+ dayofmonth = 31
678
+ };
679
+ {
680
+ description = "last Wednesday of August 2013";
681
+ year = 2013;
682
+ month = 8;
683
+ week = Last;
684
+ dayofweek = Wednesday;
685
+ dayofmonth = 28
686
+ };
687
+ {
688
+ description = "last Thursday of September 2013";
689
+ year = 2013;
690
+ month = 9;
691
+ week = Last;
692
+ dayofweek = Thursday;
693
+ dayofmonth = 26
694
+ };
695
+ {
696
+ description = "last Thursday of October 2013";
697
+ year = 2013;
698
+ month = 10;
699
+ week = Last;
700
+ dayofweek = Thursday;
701
+ dayofmonth = 31
702
+ };
703
+ {
704
+ description = "last Friday of November 2013";
705
+ year = 2013;
706
+ month = 11;
707
+ week = Last;
708
+ dayofweek = Friday;
709
+ dayofmonth = 29
710
+ };
711
+ {
712
+ description = "last Friday of December 2013";
713
+ year = 2013;
714
+ month = 12;
715
+ week = Last;
716
+ dayofweek = Friday;
717
+ dayofmonth = 27
718
+ };
719
+ {
720
+ description = "last Saturday of January 2013";
721
+ year = 2013;
722
+ month = 1;
723
+ week = Last;
724
+ dayofweek = Saturday;
725
+ dayofmonth = 26
726
+ };
727
+ {
728
+ description = "last Saturday of February 2013";
729
+ year = 2013;
730
+ month = 2;
731
+ week = Last;
732
+ dayofweek = Saturday;
733
+ dayofmonth = 23
734
+ };
735
+ {
736
+ description = "last Sunday of March 2013";
737
+ year = 2013;
738
+ month = 3;
739
+ week = Last;
740
+ dayofweek = Sunday;
741
+ dayofmonth = 31
742
+ };
743
+ {
744
+ description = "last Sunday of April 2013";
745
+ year = 2013;
746
+ month = 4;
747
+ week = Last;
748
+ dayofweek = Sunday;
749
+ dayofmonth = 28
750
+ };
751
+ {
752
+ description = "last Wednesday of February 2012";
753
+ year = 2012;
754
+ month = 2;
755
+ week = Last;
756
+ dayofweek = Wednesday;
757
+ dayofmonth = 29
758
+ };
759
+ {
760
+ description = "last Wednesday of December 2014";
761
+ year = 2014;
762
+ month = 12;
763
+ week = Last;
764
+ dayofweek = Wednesday;
765
+ dayofmonth = 31
766
+ };
767
+ {
768
+ description = "last Sunday of February 2015";
769
+ year = 2015;
770
+ month = 2;
771
+ week = Last;
772
+ dayofweek = Sunday;
773
+ dayofmonth = 22
774
+ };
775
+ {
776
+ description = "first Friday of December 2012";
777
+ year = 2012;
778
+ month = 12;
779
+ week = First;
780
+ dayofweek = Friday;
781
+ dayofmonth = 7
782
+ }
783
+ ]
784
+
785
+ let () =
786
+ run_test_tt_main ("meetup tests" >::: tests)