trackler 2.2.1.42 → 2.2.1.43

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/change/metadata.yml +2 -0
  4. data/problem-specifications/exercises/crypto-square/canonical-data.json +10 -65
  5. data/tracks/c/bin/run-tests +3 -0
  6. data/tracks/c/exercises/acronym/test/test_acronym.c +8 -0
  7. data/tracks/c/exercises/all-your-base/test/test_all_your_base.c +19 -0
  8. data/tracks/c/exercises/allergies/test/test_allergies.c +13 -0
  9. data/tracks/c/exercises/anagram/src/anagram.h +2 -2
  10. data/tracks/c/exercises/anagram/src/example.c +5 -5
  11. data/tracks/c/exercises/anagram/test/test_anagram.c +39 -29
  12. data/tracks/c/exercises/atbash-cipher/test/test_atbash_cipher.c +12 -0
  13. data/tracks/c/exercises/beer-song/test/test_beer_song.c +5 -0
  14. data/tracks/c/exercises/binary-search/test/test_binary_search.c +10 -0
  15. data/tracks/c/exercises/binary/test/test_binary.c +14 -0
  16. data/tracks/c/exercises/bob/test/test_bob.c +16 -0
  17. data/tracks/c/exercises/clock/test/test_clock.c +34 -0
  18. data/tracks/c/exercises/difference-of-squares/test/test_difference_of_squares.c +9 -0
  19. data/tracks/c/exercises/gigasecond/test/test_gigasecond.c +4 -0
  20. data/tracks/c/exercises/grains/test/test_grains.c +9 -0
  21. data/tracks/c/exercises/hamming/test/test_hamming.c +12 -0
  22. data/tracks/c/exercises/isogram/src/example.c +6 -6
  23. data/tracks/c/exercises/isogram/src/example.h +1 -1
  24. data/tracks/c/exercises/isogram/test/test_isogram.c +17 -9
  25. data/tracks/c/exercises/largest-series-product/test/test_largest_series_product.c +15 -0
  26. data/tracks/c/exercises/leap/test/test_leap.c +4 -0
  27. data/tracks/c/exercises/nth-prime/test/test_nth_prime.c +4 -0
  28. data/tracks/c/exercises/nucleotide-count/test/test_nucleotide_count.c +4 -0
  29. data/tracks/c/exercises/palindrome-products/test/test_palindrome_products.c +1 -0
  30. data/tracks/c/exercises/pangram/test/test_pangram.c +11 -0
  31. data/tracks/c/exercises/pascals-triangle/test/test_pascals_triangle.c +5 -0
  32. data/tracks/c/exercises/perfect-numbers/test/test_perfect_numbers.c +12 -0
  33. data/tracks/c/exercises/phone-number/test/test_phone_number.c +13 -0
  34. data/tracks/c/exercises/raindrops/test/test_raindrops.c +17 -0
  35. data/tracks/c/exercises/react/test/test_react.c +14 -0
  36. data/tracks/c/exercises/rna-transcription/test/test_rna_transcription.c +7 -0
  37. data/tracks/c/exercises/robot-simulator/test/test_robot_simulator.c +11 -0
  38. data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +17 -0
  39. data/tracks/c/exercises/scrabble-score/test/test_scrabble_score.c +10 -0
  40. data/tracks/c/exercises/sieve/test/test_sieve.c +4 -0
  41. data/tracks/c/exercises/space-age/test/test_space_age.c +7 -0
  42. data/tracks/c/exercises/sum-of-multiples/test/test_sum_of_multiples.c +11 -0
  43. data/tracks/c/exercises/triangle/test/test_triangle.c +15 -0
  44. data/tracks/c/exercises/word-count/test/test_word_count.c +10 -0
  45. data/tracks/dart/.travis.yml +2 -7
  46. data/tracks/dart/bin/check_formatting +9 -0
  47. data/tracks/dart/exercises/bob/pubspec.lock +26 -26
  48. data/tracks/dart/exercises/difference-of-squares/pubspec.lock +26 -26
  49. data/tracks/dart/exercises/gigasecond/pubspec.lock +26 -26
  50. data/tracks/dart/exercises/hamming/pubspec.lock +26 -26
  51. data/tracks/dart/exercises/hello-world/pubspec.lock +26 -26
  52. data/tracks/dart/exercises/leap/pubspec.lock +26 -26
  53. data/tracks/dart/exercises/rna-transcription/pubspec.lock +26 -26
  54. data/tracks/dart/exercises/rna-transcription/test/rna_transcription_test.dart +1 -1
  55. data/tracks/dart/pubspec.lock +42 -30
  56. data/tracks/dart/pubspec.yaml +3 -3
  57. data/tracks/dart/test/exercises_test.dart +52 -14
  58. data/tracks/dart/tool/create-exercise +1 -1
  59. data/tracks/erlang/.travis.yml +2 -2
  60. data/tracks/erlang/config.json +10 -0
  61. data/tracks/erlang/exercises/bank-account/src/example.erl +67 -41
  62. data/tracks/erlang/exercises/bank-account/test/bank_account_tests.erl +0 -6
  63. data/tracks/erlang/exercises/luhn/src/example.erl +32 -14
  64. data/tracks/erlang/exercises/luhn/test/luhn_tests.erl +36 -10
  65. data/tracks/erlang/exercises/two-fer/README.md +19 -0
  66. data/tracks/erlang/exercises/two-fer/include/exercism.hrl +11 -0
  67. data/tracks/erlang/exercises/two-fer/rebar.config +30 -0
  68. data/tracks/erlang/exercises/two-fer/src/example.erl +11 -0
  69. data/tracks/erlang/exercises/two-fer/src/two_fer.app.src +9 -0
  70. data/tracks/erlang/exercises/two-fer/src/two_fer.erl +11 -0
  71. data/tracks/erlang/exercises/two-fer/test/two_fer_tests.erl +15 -0
  72. data/tracks/java/config.json +26 -3
  73. data/tracks/java/exercises/list-ops/.meta/hints.md +4 -0
  74. data/tracks/javascript/config.json +14 -0
  75. data/tracks/javascript/docs/ABOUT.md +16 -9
  76. data/tracks/javascript/exercises/diffie-hellman/README.md +73 -0
  77. data/tracks/javascript/exercises/diffie-hellman/diffie-hellman.spec.js +73 -0
  78. data/tracks/javascript/exercises/diffie-hellman/example.js +48 -0
  79. data/tracks/julia/config.json +1 -1
  80. data/tracks/python/exercises/accumulate/accumulate.py +1 -1
  81. data/tracks/python/exercises/allergies/allergies.py +2 -2
  82. data/tracks/python/exercises/alphametics/alphametics.py +1 -1
  83. data/tracks/python/exercises/anagram/anagram.py +1 -1
  84. data/tracks/python/exercises/binary-search/binary_search.py +1 -1
  85. data/tracks/python/exercises/binary/binary.py +1 -1
  86. data/tracks/python/exercises/collatz-conjecture/collatz_conjecture.py +1 -1
  87. data/tracks/python/exercises/crypto-square/crypto_square.py +1 -1
  88. data/tracks/python/exercises/diamond/diamond.py +1 -1
  89. data/tracks/python/exercises/grep/grep.py +2 -0
  90. data/tracks/python/exercises/hello-world/hello_world.py +1 -1
  91. data/tracks/python/exercises/largest-series-product/largest_series_product.py +1 -1
  92. data/tracks/python/exercises/minesweeper/minesweeper.py +2 -1
  93. data/tracks/python/exercises/nucleotide-count/nucleotide_count.py +2 -2
  94. data/tracks/python/exercises/ocr-numbers/ocr_numbers.py +2 -2
  95. data/tracks/python/exercises/octal/octal.py +1 -1
  96. data/tracks/python/exercises/pangram/pangram.py +1 -1
  97. data/tracks/python/exercises/pascals-triangle/pascals_triangle.py +3 -3
  98. data/tracks/python/exercises/poker/poker.py +1 -1
  99. data/tracks/python/exercises/prime-factors/prime_factors.py +1 -1
  100. data/tracks/python/exercises/protein-translation/protein_translation.py +2 -2
  101. data/tracks/python/exercises/proverb/proverb.py +1 -1
  102. data/tracks/python/exercises/queen-attack/queen_attack.py +2 -2
  103. data/tracks/python/exercises/rail-fence-cipher/rail_fence_cipher.py +3 -3
  104. data/tracks/python/exercises/roman-numerals/roman_numerals.py +1 -1
  105. data/tracks/python/exercises/rotational-cipher/rotational_cipher.py +1 -1
  106. data/tracks/python/exercises/say/say.py +1 -1
  107. data/tracks/python/exercises/secret-handshake/secret_handshake.py +2 -2
  108. data/tracks/python/exercises/space-age/space_age.py +1 -1
  109. data/tracks/python/exercises/tournament/tournament.py +1 -1
  110. data/tracks/python/exercises/trinary/trinary.py +1 -1
  111. data/tracks/python/exercises/two-fer/two_fer.py +1 -1
  112. data/tracks/python/exercises/word-count/word_count.py +1 -1
  113. data/tracks/ruby/lib/generator/exercise_case.rb +1 -1
  114. data/tracks/ruby/test/generator/exercise_case_test.rb +10 -0
  115. data/tracks/scala/testgen/src/main/resources/version-check-ignore.txt +1 -2
  116. data/tracks/sml/exercises/accumulate/README.md +19 -14
  117. data/tracks/sml/exercises/accumulate/accumulate.sml +1 -1
  118. data/tracks/sml/exercises/accumulate/example.sml +2 -2
  119. data/tracks/sml/exercises/accumulate/test.sml +26 -56
  120. data/tracks/sml/exercises/accumulate/testlib.sml +159 -0
  121. metadata +15 -2
@@ -10,7 +10,7 @@ void main() {
10
10
  final result = rnaTranscription.toRna("C");
11
11
 
12
12
  expect(result, equals("G"));
13
- });
13
+ }, skip: false);
14
14
 
15
15
  test("transcribes guanine to cytosine", () {
16
16
  final result = rnaTranscription.toRna("G");
@@ -6,7 +6,7 @@ packages:
6
6
  name: analyzer
7
7
  url: "https://pub.dartlang.org"
8
8
  source: hosted
9
- version: "0.30.0+2"
9
+ version: "0.30.0+4"
10
10
  args:
11
11
  description:
12
12
  name: args
@@ -24,7 +24,7 @@ packages:
24
24
  name: barback
25
25
  url: "https://pub.dartlang.org"
26
26
  source: hosted
27
- version: "0.15.2+11"
27
+ version: "0.15.2+12"
28
28
  boolean_selector:
29
29
  description:
30
30
  name: boolean_selector
@@ -42,13 +42,13 @@ packages:
42
42
  name: cli_util
43
43
  url: "https://pub.dartlang.org"
44
44
  source: hosted
45
- version: "0.1.1"
45
+ version: "0.1.2+1"
46
46
  collection:
47
47
  description:
48
48
  name: collection
49
49
  url: "https://pub.dartlang.org"
50
50
  source: hosted
51
- version: "1.14.1"
51
+ version: "1.14.3"
52
52
  convert:
53
53
  description:
54
54
  name: convert
@@ -60,31 +60,31 @@ packages:
60
60
  name: crypto
61
61
  url: "https://pub.dartlang.org"
62
62
  source: hosted
63
- version: "2.0.1"
63
+ version: "2.0.2+1"
64
64
  csslib:
65
65
  description:
66
66
  name: csslib
67
67
  url: "https://pub.dartlang.org"
68
68
  source: hosted
69
- version: "0.14.0"
69
+ version: "0.14.1"
70
70
  dart_style:
71
71
  description:
72
72
  name: dart_style
73
73
  url: "https://pub.dartlang.org"
74
74
  source: hosted
75
- version: "1.0.6"
75
+ version: "1.0.8"
76
76
  front_end:
77
77
  description:
78
78
  name: front_end
79
79
  url: "https://pub.dartlang.org"
80
80
  source: hosted
81
- version: "0.1.0-alpha.4"
81
+ version: "0.1.0-alpha.4.1"
82
82
  glob:
83
83
  description:
84
84
  name: glob
85
85
  url: "https://pub.dartlang.org"
86
86
  source: hosted
87
- version: "1.1.3"
87
+ version: "1.1.5"
88
88
  html:
89
89
  description:
90
90
  name: html
@@ -96,13 +96,13 @@ packages:
96
96
  name: http
97
97
  url: "https://pub.dartlang.org"
98
98
  source: hosted
99
- version: "0.11.3+13"
99
+ version: "0.11.3+15"
100
100
  http_multi_server:
101
101
  description:
102
102
  name: http_multi_server
103
103
  url: "https://pub.dartlang.org"
104
104
  source: hosted
105
- version: "2.0.3"
105
+ version: "2.0.4"
106
106
  http_parser:
107
107
  description:
108
108
  name: http_parser
@@ -114,13 +114,19 @@ packages:
114
114
  name: isolate
115
115
  url: "https://pub.dartlang.org"
116
116
  source: hosted
117
- version: "1.0.0"
117
+ version: "1.1.0"
118
+ js:
119
+ description:
120
+ name: js
121
+ url: "https://pub.dartlang.org"
122
+ source: hosted
123
+ version: "0.6.1"
118
124
  kernel:
119
125
  description:
120
126
  name: kernel
121
127
  url: "https://pub.dartlang.org"
122
128
  source: hosted
123
- version: "0.3.0-alpha.1"
129
+ version: "0.3.0-alpha.1.1"
124
130
  logging:
125
131
  description:
126
132
  name: logging
@@ -132,25 +138,31 @@ packages:
132
138
  name: matcher
133
139
  url: "https://pub.dartlang.org"
134
140
  source: hosted
135
- version: "0.12.1+1"
141
+ version: "0.12.1+4"
136
142
  meta:
137
143
  description:
138
144
  name: meta
139
145
  url: "https://pub.dartlang.org"
140
146
  source: hosted
141
- version: "1.0.5"
147
+ version: "1.1.2"
142
148
  mime:
143
149
  description:
144
150
  name: mime
145
151
  url: "https://pub.dartlang.org"
146
152
  source: hosted
147
153
  version: "0.9.3"
154
+ node_preamble:
155
+ description:
156
+ name: node_preamble
157
+ url: "https://pub.dartlang.org"
158
+ source: hosted
159
+ version: "1.4.0"
148
160
  package_config:
149
161
  description:
150
162
  name: package_config
151
163
  url: "https://pub.dartlang.org"
152
164
  source: hosted
153
- version: "1.0.1"
165
+ version: "1.0.3"
154
166
  package_resolver:
155
167
  description:
156
168
  name: package_resolver
@@ -168,13 +180,13 @@ packages:
168
180
  name: plugin
169
181
  url: "https://pub.dartlang.org"
170
182
  source: hosted
171
- version: "0.2.0"
183
+ version: "0.2.0+2"
172
184
  pool:
173
185
  description:
174
186
  name: pool
175
187
  url: "https://pub.dartlang.org"
176
188
  source: hosted
177
- version: "1.3.1"
189
+ version: "1.3.3"
178
190
  pub_semver:
179
191
  description:
180
192
  name: pub_semver
@@ -186,25 +198,25 @@ packages:
186
198
  name: shelf
187
199
  url: "https://pub.dartlang.org"
188
200
  source: hosted
189
- version: "0.6.8"
201
+ version: "0.7.0"
190
202
  shelf_packages_handler:
191
203
  description:
192
204
  name: shelf_packages_handler
193
205
  url: "https://pub.dartlang.org"
194
206
  source: hosted
195
- version: "1.0.0"
207
+ version: "1.0.3"
196
208
  shelf_static:
197
209
  description:
198
210
  name: shelf_static
199
211
  url: "https://pub.dartlang.org"
200
212
  source: hosted
201
- version: "0.2.4"
213
+ version: "0.2.5"
202
214
  shelf_web_socket:
203
215
  description:
204
216
  name: shelf_web_socket
205
217
  url: "https://pub.dartlang.org"
206
218
  source: hosted
207
- version: "0.2.1"
219
+ version: "0.2.2"
208
220
  source_map_stack_trace:
209
221
  description:
210
222
  name: source_map_stack_trace
@@ -228,13 +240,13 @@ packages:
228
240
  name: stack_trace
229
241
  url: "https://pub.dartlang.org"
230
242
  source: hosted
231
- version: "1.7.3"
243
+ version: "1.8.2"
232
244
  stream_channel:
233
245
  description:
234
246
  name: stream_channel
235
247
  url: "https://pub.dartlang.org"
236
248
  source: hosted
237
- version: "1.6.1"
249
+ version: "1.6.2"
238
250
  string_scanner:
239
251
  description:
240
252
  name: string_scanner
@@ -252,13 +264,13 @@ packages:
252
264
  name: test
253
265
  url: "https://pub.dartlang.org"
254
266
  source: hosted
255
- version: "0.12.23+1"
267
+ version: "0.12.24+8"
256
268
  typed_data:
257
269
  description:
258
270
  name: typed_data
259
271
  url: "https://pub.dartlang.org"
260
272
  source: hosted
261
- version: "1.1.3"
273
+ version: "1.1.5"
262
274
  utf:
263
275
  description:
264
276
  name: utf
@@ -270,18 +282,18 @@ packages:
270
282
  name: watcher
271
283
  url: "https://pub.dartlang.org"
272
284
  source: hosted
273
- version: "0.9.7+3"
285
+ version: "0.9.7+4"
274
286
  web_socket_channel:
275
287
  description:
276
288
  name: web_socket_channel
277
289
  url: "https://pub.dartlang.org"
278
290
  source: hosted
279
- version: "1.0.4"
291
+ version: "1.0.6"
280
292
  yaml:
281
293
  description:
282
294
  name: yaml
283
295
  url: "https://pub.dartlang.org"
284
296
  source: hosted
285
- version: "2.1.12"
297
+ version: "2.1.13"
286
298
  sdks:
287
- dart: ">=1.23.0 <2.0.0"
299
+ dart: ">=1.23.0 <2.0.0-dev.infinity"
@@ -2,7 +2,7 @@ name: exercism_dart
2
2
  authors:
3
3
  - SuperPaintman <SuperPaintmanDeveloper@gmail.com>
4
4
  dev_dependencies:
5
- test: '0.12.23+1'
6
5
  args: '0.13.7'
7
- yaml: '2.1.12'
8
- dart_style: '1.0.6'
6
+ dart_style: '>=1.0.8 <2.0.0'
7
+ test: '>=0.12.24+8 <0.13.0'
8
+ yaml: '>=2.1.12 <2.2.0'
@@ -27,14 +27,37 @@ Future runCmd(List<String> cmds) async {
27
27
  assert(res.exitCode == 0);
28
28
  }
29
29
 
30
+ Future<String> getPackageName() async {
31
+ final pubspec = new File("pubspec.yaml");
32
+
33
+ final packageName = loadYaml(await pubspec.readAsString())["name"];
34
+
35
+ return packageName;
36
+ }
37
+
38
+ Future locateExercismDirAndExecuteTests() async {
39
+ final exercisesRootDir = new Directory("exercises");
40
+
41
+ assert(await exercisesRootDir.exists());
42
+
43
+ final exercisesDirs = exercisesRootDir.listSync().where((d) => d is Directory);
44
+
45
+ /// Sort directories alphabetically
46
+ final sortedExerciseDirs = exercisesDirs.toList();
47
+ sortedExerciseDirs.sort((a, b) => a.path.compareTo(b.path));
48
+
49
+ for (FileSystemEntity dir in sortedExerciseDirs) {
50
+ await runTest(dir.path);
51
+ }
52
+ }
53
+
54
+ /// Execute a single test
30
55
  Future runTest(String path) async {
31
56
  final current = Directory.current;
32
57
 
33
58
  Directory.current = path;
34
59
 
35
- final pubspec = new File("pubspec.yaml");
36
-
37
- final packageName = loadYaml(await pubspec.readAsString())["name"];
60
+ String packageName = await getPackageName();
38
61
 
39
62
  print("""
40
63
  ================================================================================
@@ -45,11 +68,18 @@ Running tests for: $packageName
45
68
  await runCmd(["cp", "lib/${packageName}.dart", "lib/${packageName}.dart.bu"]);
46
69
  await runCmd(["cp", "test/${packageName}_test.dart", "test/${packageName}_test.dart.bu"]);
47
70
  try {
48
- for (var cmds in [
49
- ["cp", "lib/example.dart", "lib/${packageName}.dart"], // Replace main file with example
50
- ["sed", "-i", "-e", "s/\\bskip:\\s*true\\b/skip: false/g", "test/${packageName}_test.dart"], // Enable all tests
51
- ["pub", "get"], // Pull dependencies
52
- ["pub", "run", "test"] // Run tests
71
+ for (List<String> cmds in [
72
+ /// Replace main file with example
73
+ ["cp", "lib/example.dart", "lib/${packageName}.dart"],
74
+
75
+ /// Enable all tests
76
+ ["sed", "-i", "-e", "s/\\bskip:\\s*true\\b/skip: false/g", "test/${packageName}_test.dart"],
77
+
78
+ /// Pull dependencies
79
+ ["pub", "get"],
80
+
81
+ /// Run tests
82
+ ["pub", "run", "test"]
53
83
  ]) {
54
84
  await runCmd(cmds);
55
85
  }
@@ -61,16 +91,24 @@ Running tests for: $packageName
61
91
  }
62
92
  }
63
93
 
94
+ /// Execute all the tests under the exercise directory
64
95
  Future runAllTests() async {
65
- final exercisesRootDir = new Directory("exercises");
96
+ final dartExercismRootDir = new Directory("..");
66
97
 
67
- assert(await exercisesRootDir.exists());
98
+ assert(await dartExercismRootDir.exists());
68
99
 
69
- final exercisesDirs = exercisesRootDir.listSync().where((d) => d is Directory);
100
+ await locateExercismDirAndExecuteTests();
70
101
 
71
- for (var dir in exercisesDirs) {
72
- await runTest(dir.path);
73
- }
102
+ Directory.current = dartExercismRootDir.parent;
103
+
104
+ String packageName = await getPackageName();
105
+
106
+ print("""
107
+
108
+ ================================================================================
109
+ Running tests for: $packageName
110
+ ================================================================================
111
+ """);
74
112
  }
75
113
 
76
114
  void main() {
@@ -72,7 +72,7 @@ void main() {
72
72
  String pubTemplate(String name) => """
73
73
  name: '${snakeCase(name)}'
74
74
  dev_dependencies:
75
- test: '0.12.23+1'
75
+ test: '<0.13.0'
76
76
  """;
77
77
 
78
78
  Future main(args) async {
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  language: erlang
3
3
  otp_release:
4
- - 17.5
5
4
  - 18.3
6
- - 19.2
5
+ - 19.3
6
+ - 20.0
7
7
  install:
8
8
  - "./_test/bootstrap.sh"
9
9
  - rvm install 2.2.5
@@ -192,6 +192,16 @@
192
192
 
193
193
  ]
194
194
  },
195
+ {
196
+ "uuid": "1a8abaa2-04f5-0e80-7986-5fb33995971caeb1496",
197
+ "slug": "two-fer",
198
+ "core": false,
199
+ "unlocked_by": null,
200
+ "difficulty": 3,
201
+ "topics": [
202
+
203
+ ]
204
+ },
195
205
  {
196
206
  "uuid": "a2d4ca29-54e2-4969-bfc9-ee483acf9caf",
197
207
  "slug": "robot-simulator",
@@ -1,54 +1,80 @@
1
1
  -module(example).
2
2
 
3
- -export( [balance/1, charge/2, close/1, create/0, deposit/2, withdraw/2, test_version/0] ).
3
+ -export([
4
+ balance/1,
5
+ charge/2,
6
+ close/1,
7
+ create/0,
8
+ deposit/2,
9
+ withdraw/2,
10
+ test_version/0
11
+ ]).
4
12
 
13
+ -export([
14
+ init/1,
15
+ handle_call/3,
16
+ handle_cast/2
17
+ ]).
5
18
 
6
- balance( Pid ) -> call( erlang:is_process_alive(Pid), Pid, balance, 0 ).
19
+ -behaviour(gen_server).
7
20
 
8
- charge( Pid, Amount ) when Amount > 0 -> call( erlang:is_process_alive(Pid), Pid, charge, Amount );
9
- charge( _Pid, _Amount ) -> 0.
21
+ -record(account, {pid}).
10
22
 
11
- close( Pid ) -> call( erlang:is_process_alive(Pid), Pid, close, 0 ).
12
23
 
13
- create() -> erlang:spawn( fun () -> loop(0) end ).
24
+ test_version() ->
25
+ 1.
14
26
 
15
- deposit( Pid, Amount ) when Amount > 0 -> Pid ! {deposit, Amount};
16
- deposit( _Pid, _Amount ) -> ok.
17
27
 
18
- withdraw( Pid, Amount ) when Amount > 0 -> call( erlang:is_process_alive(Pid), Pid, withdraw, Amount );
19
- withdraw( _Pid, _Amount ) -> 0.
28
+ %%% Public API
20
29
 
21
- test_version() ->
22
- 1.
30
+ create() ->
31
+ {ok, PID} = gen_server:start(?MODULE, [], []),
32
+ #account{pid=PID}.
33
+
34
+ balance(#account{pid=PID}) ->
35
+ gen_server:call(PID, balance, infinity).
36
+
37
+ charge(#account{pid=PID}, Amount) ->
38
+ gen_server:call(PID, {charge, Amount}, infinity).
39
+
40
+ close(#account{pid=PID}) ->
41
+ gen_server:call(PID, close, infinity).
42
+
43
+ deposit(#account{pid=PID}, Amount) ->
44
+ gen_server:call(PID, {deposit, Amount}, infinity).
45
+
46
+ withdraw(#account{pid=PID}, Amount) ->
47
+ gen_server:call(PID, {withdraw, Amount}, infinity).
48
+
49
+ %%% gen_server API
50
+
51
+ init([]) ->
52
+ {ok, 0}.
23
53
 
54
+ handle_call(_, _From, closed) ->
55
+ {reply, {error, account_closed}, closed};
56
+ handle_call(close, _From, Balance) ->
57
+ {reply, Balance, closed};
58
+ handle_call(balance, _From, Balance) ->
59
+ {reply, Balance, Balance};
60
+ handle_call({deposit, Amount}, _From, Balance) when Amount > 0 ->
61
+ {reply, Amount, Balance + Amount};
62
+ handle_call({deposit, _}, _From, Balance) ->
63
+ {reply, Balance, Balance};
64
+ handle_call({withdraw, Amount}, _From, Balance) when Amount > Balance ->
65
+ {reply, Balance, 0};
66
+ handle_call({withdraw, Amount}, _From, Balance) when Amount > 0 ->
67
+ Balance1 = Balance - Amount,
68
+ {reply, Amount, Balance1};
69
+ handle_call({withdraw, _}, _From, Balance) ->
70
+ {reply, 0, Balance};
71
+ handle_call({charge, Amount}, _From, Balance) when Amount > Balance ->
72
+ {reply, 0, Balance};
73
+ handle_call({charge, Amount}, _From, Balance) when Amount > 0 ->
74
+ {reply, Amount, Balance - Amount};
75
+ handle_call({charge, _}, _From, Balance) ->
76
+ {reply, 0, Balance}.
24
77
 
25
78
 
26
- call( true, Pid, Request, Argument ) ->
27
- Pid ! {Request, Argument, erlang:self()},
28
- receive
29
- {Request, Answer} -> Answer
30
- end;
31
- call( false, _Pid, _Request, _Argument ) ->
32
- {error, account_closed}.
33
-
34
- loop( Balance ) ->
35
- receive
36
- {balance, _Argument, Pid} ->
37
- Pid ! {balance, Balance},
38
- loop( Balance );
39
- {charge, Amount, Pid} ->
40
- Charge = loop_charge( Balance, Amount ),
41
- Pid ! {charge, Charge},
42
- loop( Balance - Charge );
43
- {close, _Argument, Pid} ->
44
- Pid ! {close, Balance};
45
- {deposit, Amount} ->
46
- loop( Balance + Amount );
47
- {withdraw, Amount, Pid} ->
48
- Withdraw = erlang:min( Balance, Amount ),
49
- Pid ! {withdraw, Withdraw},
50
- loop( Balance - Withdraw )
51
- end.
52
-
53
- loop_charge( Balance, Amount ) when Balance >= Amount -> Amount;
54
- loop_charge( _Balance, _Amount ) -> 0.
79
+ handle_cast(_, Balance) ->
80
+ {noreply, Balance}.