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.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/change/metadata.yml +2 -0
- data/problem-specifications/exercises/crypto-square/canonical-data.json +10 -65
- data/tracks/c/bin/run-tests +3 -0
- data/tracks/c/exercises/acronym/test/test_acronym.c +8 -0
- data/tracks/c/exercises/all-your-base/test/test_all_your_base.c +19 -0
- data/tracks/c/exercises/allergies/test/test_allergies.c +13 -0
- data/tracks/c/exercises/anagram/src/anagram.h +2 -2
- data/tracks/c/exercises/anagram/src/example.c +5 -5
- data/tracks/c/exercises/anagram/test/test_anagram.c +39 -29
- data/tracks/c/exercises/atbash-cipher/test/test_atbash_cipher.c +12 -0
- data/tracks/c/exercises/beer-song/test/test_beer_song.c +5 -0
- data/tracks/c/exercises/binary-search/test/test_binary_search.c +10 -0
- data/tracks/c/exercises/binary/test/test_binary.c +14 -0
- data/tracks/c/exercises/bob/test/test_bob.c +16 -0
- data/tracks/c/exercises/clock/test/test_clock.c +34 -0
- data/tracks/c/exercises/difference-of-squares/test/test_difference_of_squares.c +9 -0
- data/tracks/c/exercises/gigasecond/test/test_gigasecond.c +4 -0
- data/tracks/c/exercises/grains/test/test_grains.c +9 -0
- data/tracks/c/exercises/hamming/test/test_hamming.c +12 -0
- data/tracks/c/exercises/isogram/src/example.c +6 -6
- data/tracks/c/exercises/isogram/src/example.h +1 -1
- data/tracks/c/exercises/isogram/test/test_isogram.c +17 -9
- data/tracks/c/exercises/largest-series-product/test/test_largest_series_product.c +15 -0
- data/tracks/c/exercises/leap/test/test_leap.c +4 -0
- data/tracks/c/exercises/nth-prime/test/test_nth_prime.c +4 -0
- data/tracks/c/exercises/nucleotide-count/test/test_nucleotide_count.c +4 -0
- data/tracks/c/exercises/palindrome-products/test/test_palindrome_products.c +1 -0
- data/tracks/c/exercises/pangram/test/test_pangram.c +11 -0
- data/tracks/c/exercises/pascals-triangle/test/test_pascals_triangle.c +5 -0
- data/tracks/c/exercises/perfect-numbers/test/test_perfect_numbers.c +12 -0
- data/tracks/c/exercises/phone-number/test/test_phone_number.c +13 -0
- data/tracks/c/exercises/raindrops/test/test_raindrops.c +17 -0
- data/tracks/c/exercises/react/test/test_react.c +14 -0
- data/tracks/c/exercises/rna-transcription/test/test_rna_transcription.c +7 -0
- data/tracks/c/exercises/robot-simulator/test/test_robot_simulator.c +11 -0
- data/tracks/c/exercises/roman-numerals/test/test_roman_numerals.c +17 -0
- data/tracks/c/exercises/scrabble-score/test/test_scrabble_score.c +10 -0
- data/tracks/c/exercises/sieve/test/test_sieve.c +4 -0
- data/tracks/c/exercises/space-age/test/test_space_age.c +7 -0
- data/tracks/c/exercises/sum-of-multiples/test/test_sum_of_multiples.c +11 -0
- data/tracks/c/exercises/triangle/test/test_triangle.c +15 -0
- data/tracks/c/exercises/word-count/test/test_word_count.c +10 -0
- data/tracks/dart/.travis.yml +2 -7
- data/tracks/dart/bin/check_formatting +9 -0
- data/tracks/dart/exercises/bob/pubspec.lock +26 -26
- data/tracks/dart/exercises/difference-of-squares/pubspec.lock +26 -26
- data/tracks/dart/exercises/gigasecond/pubspec.lock +26 -26
- data/tracks/dart/exercises/hamming/pubspec.lock +26 -26
- data/tracks/dart/exercises/hello-world/pubspec.lock +26 -26
- data/tracks/dart/exercises/leap/pubspec.lock +26 -26
- data/tracks/dart/exercises/rna-transcription/pubspec.lock +26 -26
- data/tracks/dart/exercises/rna-transcription/test/rna_transcription_test.dart +1 -1
- data/tracks/dart/pubspec.lock +42 -30
- data/tracks/dart/pubspec.yaml +3 -3
- data/tracks/dart/test/exercises_test.dart +52 -14
- data/tracks/dart/tool/create-exercise +1 -1
- data/tracks/erlang/.travis.yml +2 -2
- data/tracks/erlang/config.json +10 -0
- data/tracks/erlang/exercises/bank-account/src/example.erl +67 -41
- data/tracks/erlang/exercises/bank-account/test/bank_account_tests.erl +0 -6
- data/tracks/erlang/exercises/luhn/src/example.erl +32 -14
- data/tracks/erlang/exercises/luhn/test/luhn_tests.erl +36 -10
- data/tracks/erlang/exercises/two-fer/README.md +19 -0
- data/tracks/erlang/exercises/two-fer/include/exercism.hrl +11 -0
- data/tracks/erlang/exercises/two-fer/rebar.config +30 -0
- data/tracks/erlang/exercises/two-fer/src/example.erl +11 -0
- data/tracks/erlang/exercises/two-fer/src/two_fer.app.src +9 -0
- data/tracks/erlang/exercises/two-fer/src/two_fer.erl +11 -0
- data/tracks/erlang/exercises/two-fer/test/two_fer_tests.erl +15 -0
- data/tracks/java/config.json +26 -3
- data/tracks/java/exercises/list-ops/.meta/hints.md +4 -0
- data/tracks/javascript/config.json +14 -0
- data/tracks/javascript/docs/ABOUT.md +16 -9
- data/tracks/javascript/exercises/diffie-hellman/README.md +73 -0
- data/tracks/javascript/exercises/diffie-hellman/diffie-hellman.spec.js +73 -0
- data/tracks/javascript/exercises/diffie-hellman/example.js +48 -0
- data/tracks/julia/config.json +1 -1
- data/tracks/python/exercises/accumulate/accumulate.py +1 -1
- data/tracks/python/exercises/allergies/allergies.py +2 -2
- data/tracks/python/exercises/alphametics/alphametics.py +1 -1
- data/tracks/python/exercises/anagram/anagram.py +1 -1
- data/tracks/python/exercises/binary-search/binary_search.py +1 -1
- data/tracks/python/exercises/binary/binary.py +1 -1
- data/tracks/python/exercises/collatz-conjecture/collatz_conjecture.py +1 -1
- data/tracks/python/exercises/crypto-square/crypto_square.py +1 -1
- data/tracks/python/exercises/diamond/diamond.py +1 -1
- data/tracks/python/exercises/grep/grep.py +2 -0
- data/tracks/python/exercises/hello-world/hello_world.py +1 -1
- data/tracks/python/exercises/largest-series-product/largest_series_product.py +1 -1
- data/tracks/python/exercises/minesweeper/minesweeper.py +2 -1
- data/tracks/python/exercises/nucleotide-count/nucleotide_count.py +2 -2
- data/tracks/python/exercises/ocr-numbers/ocr_numbers.py +2 -2
- data/tracks/python/exercises/octal/octal.py +1 -1
- data/tracks/python/exercises/pangram/pangram.py +1 -1
- data/tracks/python/exercises/pascals-triangle/pascals_triangle.py +3 -3
- data/tracks/python/exercises/poker/poker.py +1 -1
- data/tracks/python/exercises/prime-factors/prime_factors.py +1 -1
- data/tracks/python/exercises/protein-translation/protein_translation.py +2 -2
- data/tracks/python/exercises/proverb/proverb.py +1 -1
- data/tracks/python/exercises/queen-attack/queen_attack.py +2 -2
- data/tracks/python/exercises/rail-fence-cipher/rail_fence_cipher.py +3 -3
- data/tracks/python/exercises/roman-numerals/roman_numerals.py +1 -1
- data/tracks/python/exercises/rotational-cipher/rotational_cipher.py +1 -1
- data/tracks/python/exercises/say/say.py +1 -1
- data/tracks/python/exercises/secret-handshake/secret_handshake.py +2 -2
- data/tracks/python/exercises/space-age/space_age.py +1 -1
- data/tracks/python/exercises/tournament/tournament.py +1 -1
- data/tracks/python/exercises/trinary/trinary.py +1 -1
- data/tracks/python/exercises/two-fer/two_fer.py +1 -1
- data/tracks/python/exercises/word-count/word_count.py +1 -1
- data/tracks/ruby/lib/generator/exercise_case.rb +1 -1
- data/tracks/ruby/test/generator/exercise_case_test.rb +10 -0
- data/tracks/scala/testgen/src/main/resources/version-check-ignore.txt +1 -2
- data/tracks/sml/exercises/accumulate/README.md +19 -14
- data/tracks/sml/exercises/accumulate/accumulate.sml +1 -1
- data/tracks/sml/exercises/accumulate/example.sml +2 -2
- data/tracks/sml/exercises/accumulate/test.sml +26 -56
- data/tracks/sml/exercises/accumulate/testlib.sml +159 -0
- metadata +15 -2
data/tracks/dart/pubspec.lock
CHANGED
@@ -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+
|
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+
|
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.
|
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.
|
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.
|
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.
|
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+
|
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.
|
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.
|
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+
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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+
|
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.
|
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.
|
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"
|
data/tracks/dart/pubspec.yaml
CHANGED
@@ -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
|
-
|
8
|
-
|
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
|
-
|
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 (
|
49
|
-
|
50
|
-
["
|
51
|
-
|
52
|
-
|
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
|
96
|
+
final dartExercismRootDir = new Directory("..");
|
66
97
|
|
67
|
-
assert(await
|
98
|
+
assert(await dartExercismRootDir.exists());
|
68
99
|
|
69
|
-
|
100
|
+
await locateExercismDirAndExecuteTests();
|
70
101
|
|
71
|
-
|
72
|
-
|
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() {
|
data/tracks/erlang/.travis.yml
CHANGED
data/tracks/erlang/config.json
CHANGED
@@ -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(
|
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
|
-
|
19
|
+
-behaviour(gen_server).
|
7
20
|
|
8
|
-
|
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
|
-
|
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
|
-
|
19
|
-
withdraw( _Pid, _Amount ) -> 0.
|
28
|
+
%%% Public API
|
20
29
|
|
21
|
-
|
22
|
-
|
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
|
-
|
27
|
-
|
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}.
|