trackler 2.1.0.3 → 2.1.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8fb16c70320bfab64f3c4ce4ebbbb49672f9d74e
4
- data.tar.gz: 71e5765ed2b9ef40d7ca43c24237aad49d0b0680
3
+ metadata.gz: 0f4a5eeade9a4606b722ee2797e1418b0246dbb8
4
+ data.tar.gz: 3dbb5988e94050dc9674eb5091f042ddae0e38f8
5
5
  SHA512:
6
- metadata.gz: 14f69d678943dcb0f9ee681022f033a4c2d2d1b24bb6030e9fed9cca560eaf380d82d0c4d21b11aa2273b46d51d3ca3becb3be616cc87c4a2e641733042c616b
7
- data.tar.gz: 635b4af5725bbef3017df9d3b75c24f6cd2e397e686e6bedd6c08e422bf5f7bd6892d0a1ff899288ba6cec9e93f23d0557a8d1cf334922ac608d77f49812e521
6
+ metadata.gz: 7330e08438242aab42d3104d5e23a7c735c69254ca1f3e77dfc090b0182f21e2700de2ec0ef288853c6d4738b4bf7cd2c9e2869820d931f7584690537f584d30
7
+ data.tar.gz: 021fe446632e0bf3a9a0511f8f082f166097821cea4fcdb09049c1332b458e651cfca1ea1d230c565c2be33fd8e50df36a88b07407bea66fef046fdebccb8cf9
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "exercise": "clock",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "comments": [
5
5
  "Most languages require constructing a clock with initial values,",
6
6
  "adding a positive or negative number of minutes, and testing equality",
@@ -10,7 +10,7 @@
10
10
  ],
11
11
  "cases": [
12
12
  {
13
- "description": "Test creating a new clock with an initial time.",
13
+ "description": "Create a new clock with an initial time",
14
14
  "cases": [
15
15
  {
16
16
  "description": "on the hour",
@@ -148,7 +148,7 @@
148
148
  ]
149
149
  },
150
150
  {
151
- "description": "Test adding and subtracting minutes.",
151
+ "description": "Add minutes",
152
152
  "cases": [
153
153
  {
154
154
  "description": "add minutes",
@@ -213,7 +213,12 @@
213
213
  "minute": 1,
214
214
  "add": 3500,
215
215
  "expected": "11:21"
216
- },
216
+ }
217
+ ]
218
+ },
219
+ {
220
+ "description": "Subtract minutes",
221
+ "cases": [
217
222
  {
218
223
  "description": "subtract minutes",
219
224
  "property": "add",
@@ -281,7 +286,7 @@
281
286
  ]
282
287
  },
283
288
  {
284
- "description": "Construct two separate clocks, set times, test if they are equal.",
289
+ "description": "Compare two clocks for equality",
285
290
  "cases": [
286
291
  {
287
292
  "description": "clocks with same time",
@@ -0,0 +1,676 @@
1
+ {
2
+ "exercise": "word-search",
3
+ "version": "1.0.0",
4
+ "comments": [
5
+ "Grid rows and columns are 1-indexed.",
6
+ "An expected value of -1 indicates that some sort of failure should occur."
7
+ ],
8
+ "cases": [
9
+ {
10
+ "description": "Should locate words written left to right",
11
+ "property": "search",
12
+ "grid": [
13
+ "jefblpepre",
14
+ "camdcimgtc",
15
+ "oivokprjsm",
16
+ "pbwasqroua",
17
+ "rixilelhrs",
18
+ "wolcqlirpc",
19
+ "screeaumgr",
20
+ "alxhpburyi",
21
+ "jalaycalmp",
22
+ "clojurermt"
23
+ ],
24
+ "wordsToSearchFor": [
25
+ "clojure"
26
+ ],
27
+ "expected": {
28
+ "clojure": {
29
+ "start": {
30
+ "column": 1,
31
+ "row": 10
32
+ },
33
+ "end": {
34
+ "column": 7,
35
+ "row": 10
36
+ }
37
+ }
38
+ }
39
+ },
40
+ {
41
+ "description": "Should locate words written right to left",
42
+ "property": "search",
43
+ "grid": [
44
+ "jefblpepre",
45
+ "camdcimgtc",
46
+ "oivokprjsm",
47
+ "pbwasqroua",
48
+ "rixilelhrs",
49
+ "wolcqlirpc",
50
+ "screeaumgr",
51
+ "alxhpburyi",
52
+ "jalaycalmp",
53
+ "clojurermt"
54
+ ],
55
+ "wordsToSearchFor": [
56
+ "clojure",
57
+ "elixir"
58
+ ],
59
+ "expected": {
60
+ "clojure": {
61
+ "start": {
62
+ "column": 1,
63
+ "row": 10
64
+ },
65
+ "end": {
66
+ "column": 7,
67
+ "row": 10
68
+ }
69
+ },
70
+ "elixir": {
71
+ "start": {
72
+ "column": 6,
73
+ "row": 5
74
+ },
75
+ "end": {
76
+ "column": 1,
77
+ "row": 5
78
+ }
79
+ }
80
+ }
81
+ },
82
+ {
83
+ "description": "Should locate words written top to bottom",
84
+ "property": "search",
85
+ "grid": [
86
+ "jefblpepre",
87
+ "camdcimgtc",
88
+ "oivokprjsm",
89
+ "pbwasqroua",
90
+ "rixilelhrs",
91
+ "wolcqlirpc",
92
+ "screeaumgr",
93
+ "alxhpburyi",
94
+ "jalaycalmp",
95
+ "clojurermt"
96
+ ],
97
+ "wordsToSearchFor": [
98
+ "clojure",
99
+ "elixir",
100
+ "ecmascript"
101
+ ],
102
+ "expected": {
103
+ "clojure": {
104
+ "start": {
105
+ "column": 1,
106
+ "row": 10
107
+ },
108
+ "end": {
109
+ "column": 7,
110
+ "row": 10
111
+ }
112
+ },
113
+ "elixir": {
114
+ "start": {
115
+ "column": 6,
116
+ "row": 5
117
+ },
118
+ "end": {
119
+ "column": 1,
120
+ "row": 5
121
+ }
122
+ },
123
+ "ecmascript": {
124
+ "start": {
125
+ "column": 10,
126
+ "row": 1
127
+ },
128
+ "end": {
129
+ "column": 10,
130
+ "row": 10
131
+ }
132
+ }
133
+ }
134
+ },
135
+ {
136
+ "description": "Should locate words written bottom to top",
137
+ "property": "search",
138
+ "grid": [
139
+ "jefblpepre",
140
+ "camdcimgtc",
141
+ "oivokprjsm",
142
+ "pbwasqroua",
143
+ "rixilelhrs",
144
+ "wolcqlirpc",
145
+ "screeaumgr",
146
+ "alxhpburyi",
147
+ "jalaycalmp",
148
+ "clojurermt"
149
+ ],
150
+ "wordsToSearchFor": [
151
+ "clojure",
152
+ "elixir",
153
+ "ecmascript",
154
+ "rust"
155
+ ],
156
+ "expected": {
157
+ "clojure": {
158
+ "start": {
159
+ "column": 1,
160
+ "row": 10
161
+ },
162
+ "end": {
163
+ "column": 7,
164
+ "row": 10
165
+ }
166
+ },
167
+ "elixir": {
168
+ "start": {
169
+ "column": 6,
170
+ "row": 5
171
+ },
172
+ "end": {
173
+ "column": 1,
174
+ "row": 5
175
+ }
176
+ },
177
+ "ecmascript": {
178
+ "start": {
179
+ "column": 10,
180
+ "row": 1
181
+ },
182
+ "end": {
183
+ "column": 10,
184
+ "row": 10
185
+ }
186
+ },
187
+ "rust": {
188
+ "start": {
189
+ "column": 9,
190
+ "row": 5
191
+ },
192
+ "end": {
193
+ "column": 9,
194
+ "row": 2
195
+ }
196
+ }
197
+ }
198
+ },
199
+ {
200
+ "description": "Should locate words written top left to bottom right",
201
+ "property": "search",
202
+ "grid": [
203
+ "jefblpepre",
204
+ "camdcimgtc",
205
+ "oivokprjsm",
206
+ "pbwasqroua",
207
+ "rixilelhrs",
208
+ "wolcqlirpc",
209
+ "screeaumgr",
210
+ "alxhpburyi",
211
+ "jalaycalmp",
212
+ "clojurermt"
213
+ ],
214
+ "wordsToSearchFor": [
215
+ "clojure",
216
+ "elixir",
217
+ "ecmascript",
218
+ "rust",
219
+ "java"
220
+ ],
221
+ "expected": {
222
+ "clojure": {
223
+ "start": {
224
+ "column": 1,
225
+ "row": 10
226
+ },
227
+ "end": {
228
+ "column": 7,
229
+ "row": 10
230
+ }
231
+ },
232
+ "elixir": {
233
+ "start": {
234
+ "column": 6,
235
+ "row": 5
236
+ },
237
+ "end": {
238
+ "column": 1,
239
+ "row": 5
240
+ }
241
+ },
242
+ "ecmascript": {
243
+ "start": {
244
+ "column": 10,
245
+ "row": 1
246
+ },
247
+ "end": {
248
+ "column": 10,
249
+ "row": 10
250
+ }
251
+ },
252
+ "rust": {
253
+ "start": {
254
+ "column": 9,
255
+ "row": 5
256
+ },
257
+ "end": {
258
+ "column": 9,
259
+ "row": 2
260
+ }
261
+ },
262
+ "java": {
263
+ "start": {
264
+ "column": 1,
265
+ "row": 1
266
+ },
267
+ "end": {
268
+ "column": 4,
269
+ "row": 4
270
+ }
271
+ }
272
+ }
273
+ },
274
+ {
275
+ "description": "Should locate words written bottom right to top left",
276
+ "property": "search",
277
+ "grid": [
278
+ "jefblpepre",
279
+ "camdcimgtc",
280
+ "oivokprjsm",
281
+ "pbwasqroua",
282
+ "rixilelhrs",
283
+ "wolcqlirpc",
284
+ "screeaumgr",
285
+ "alxhpburyi",
286
+ "jalaycalmp",
287
+ "clojurermt"
288
+ ],
289
+ "wordsToSearchFor": [
290
+ "clojure",
291
+ "elixir",
292
+ "ecmascript",
293
+ "rust",
294
+ "java",
295
+ "lua"
296
+ ],
297
+ "expected": {
298
+ "clojure": {
299
+ "start": {
300
+ "column": 1,
301
+ "row": 10
302
+ },
303
+ "end": {
304
+ "column": 7,
305
+ "row": 10
306
+ }
307
+ },
308
+ "elixir": {
309
+ "start": {
310
+ "column": 6,
311
+ "row": 5
312
+ },
313
+ "end": {
314
+ "column": 1,
315
+ "row": 5
316
+ }
317
+ },
318
+ "ecmascript": {
319
+ "start": {
320
+ "column": 10,
321
+ "row": 1
322
+ },
323
+ "end": {
324
+ "column": 10,
325
+ "row": 10
326
+ }
327
+ },
328
+ "rust": {
329
+ "start": {
330
+ "column": 9,
331
+ "row": 5
332
+ },
333
+ "end": {
334
+ "column": 9,
335
+ "row": 2
336
+ }
337
+ },
338
+ "java": {
339
+ "start": {
340
+ "column": 1,
341
+ "row": 1
342
+ },
343
+ "end": {
344
+ "column": 4,
345
+ "row": 4
346
+ }
347
+ },
348
+ "lua": {
349
+ "start": {
350
+ "column": 8,
351
+ "row": 9
352
+ },
353
+ "end": {
354
+ "column": 6,
355
+ "row": 7
356
+ }
357
+ }
358
+ }
359
+ },
360
+ {
361
+ "description": "Should locate words written bottom left to top right",
362
+ "property": "search",
363
+ "grid": [
364
+ "jefblpepre",
365
+ "camdcimgtc",
366
+ "oivokprjsm",
367
+ "pbwasqroua",
368
+ "rixilelhrs",
369
+ "wolcqlirpc",
370
+ "screeaumgr",
371
+ "alxhpburyi",
372
+ "jalaycalmp",
373
+ "clojurermt"
374
+ ],
375
+ "wordsToSearchFor": [
376
+ "clojure",
377
+ "elixir",
378
+ "ecmascript",
379
+ "rust",
380
+ "java",
381
+ "lua",
382
+ "lisp"
383
+ ],
384
+ "expected": {
385
+ "clojure": {
386
+ "start": {
387
+ "column": 1,
388
+ "row": 10
389
+ },
390
+ "end": {
391
+ "column": 7,
392
+ "row": 10
393
+ }
394
+ },
395
+ "elixir": {
396
+ "start": {
397
+ "column": 6,
398
+ "row": 5
399
+ },
400
+ "end": {
401
+ "column": 1,
402
+ "row": 5
403
+ }
404
+ },
405
+ "ecmascript": {
406
+ "start": {
407
+ "column": 10,
408
+ "row": 1
409
+ },
410
+ "end": {
411
+ "column": 10,
412
+ "row": 10
413
+ }
414
+ },
415
+ "rust": {
416
+ "start": {
417
+ "column": 9,
418
+ "row": 5
419
+ },
420
+ "end": {
421
+ "column": 9,
422
+ "row": 2
423
+ }
424
+ },
425
+ "java": {
426
+ "start": {
427
+ "column": 1,
428
+ "row": 1
429
+ },
430
+ "end": {
431
+ "column": 4,
432
+ "row": 4
433
+ }
434
+ },
435
+ "lua": {
436
+ "start": {
437
+ "column": 8,
438
+ "row": 9
439
+ },
440
+ "end": {
441
+ "column": 6,
442
+ "row": 7
443
+ }
444
+ },
445
+ "lisp": {
446
+ "start": {
447
+ "column": 3,
448
+ "row": 6
449
+ },
450
+ "end": {
451
+ "column": 6,
452
+ "row": 3
453
+ }
454
+ }
455
+ }
456
+ },
457
+ {
458
+ "description": "Should locate words written top right to bottom left",
459
+ "property": "search",
460
+ "grid": [
461
+ "jefblpepre",
462
+ "camdcimgtc",
463
+ "oivokprjsm",
464
+ "pbwasqroua",
465
+ "rixilelhrs",
466
+ "wolcqlirpc",
467
+ "screeaumgr",
468
+ "alxhpburyi",
469
+ "jalaycalmp",
470
+ "clojurermt"
471
+ ],
472
+ "wordsToSearchFor": [
473
+ "clojure",
474
+ "elixir",
475
+ "ecmascript",
476
+ "rust",
477
+ "java",
478
+ "lua",
479
+ "lisp",
480
+ "ruby"
481
+ ],
482
+ "expected": {
483
+ "clojure": {
484
+ "start": {
485
+ "column": 1,
486
+ "row": 10
487
+ },
488
+ "end": {
489
+ "column": 7,
490
+ "row": 10
491
+ }
492
+ },
493
+ "elixir": {
494
+ "start": {
495
+ "column": 6,
496
+ "row": 5
497
+ },
498
+ "end": {
499
+ "column": 1,
500
+ "row": 5
501
+ }
502
+ },
503
+ "ecmascript": {
504
+ "start": {
505
+ "column": 10,
506
+ "row": 1
507
+ },
508
+ "end": {
509
+ "column": 10,
510
+ "row": 10
511
+ }
512
+ },
513
+ "rust": {
514
+ "start": {
515
+ "column": 9,
516
+ "row": 5
517
+ },
518
+ "end": {
519
+ "column": 9,
520
+ "row": 2
521
+ }
522
+ },
523
+ "java": {
524
+ "start": {
525
+ "column": 1,
526
+ "row": 1
527
+ },
528
+ "end": {
529
+ "column": 4,
530
+ "row": 4
531
+ }
532
+ },
533
+ "lua": {
534
+ "start": {
535
+ "column": 8,
536
+ "row": 9
537
+ },
538
+ "end": {
539
+ "column": 6,
540
+ "row": 7
541
+ }
542
+ },
543
+ "lisp": {
544
+ "start": {
545
+ "column": 3,
546
+ "row": 6
547
+ },
548
+ "end": {
549
+ "column": 6,
550
+ "row": 3
551
+ }
552
+ },
553
+ "ruby": {
554
+ "start": {
555
+ "column": 8,
556
+ "row": 6
557
+ },
558
+ "end": {
559
+ "column": 5,
560
+ "row": 9
561
+ }
562
+ }
563
+ }
564
+ },
565
+ {
566
+ "description": "Should fail to locate a word that is not in the puzzle",
567
+ "property": "search",
568
+ "grid": [
569
+ "jefblpepre",
570
+ "camdcimgtc",
571
+ "oivokprjsm",
572
+ "pbwasqroua",
573
+ "rixilelhrs",
574
+ "wolcqlirpc",
575
+ "screeaumgr",
576
+ "alxhpburyi",
577
+ "jalaycalmp",
578
+ "clojurermt"
579
+ ],
580
+ "wordsToSearchFor": [
581
+ "clojure",
582
+ "elixir",
583
+ "ecmascript",
584
+ "rust",
585
+ "java",
586
+ "lua",
587
+ "lisp",
588
+ "ruby",
589
+ "haskell"
590
+ ],
591
+ "expected": {
592
+ "clojure": {
593
+ "start": {
594
+ "column": 1,
595
+ "row": 10
596
+ },
597
+ "end": {
598
+ "column": 7,
599
+ "row": 10
600
+ }
601
+ },
602
+ "elixir": {
603
+ "start": {
604
+ "column": 6,
605
+ "row": 5
606
+ },
607
+ "end": {
608
+ "column": 1,
609
+ "row": 5
610
+ }
611
+ },
612
+ "ecmascript": {
613
+ "start": {
614
+ "column": 10,
615
+ "row": 1
616
+ },
617
+ "end": {
618
+ "column": 10,
619
+ "row": 10
620
+ }
621
+ },
622
+ "rust": {
623
+ "start": {
624
+ "column": 9,
625
+ "row": 5
626
+ },
627
+ "end": {
628
+ "column": 9,
629
+ "row": 2
630
+ }
631
+ },
632
+ "java": {
633
+ "start": {
634
+ "column": 1,
635
+ "row": 1
636
+ },
637
+ "end": {
638
+ "column": 4,
639
+ "row": 4
640
+ }
641
+ },
642
+ "lua": {
643
+ "start": {
644
+ "column": 8,
645
+ "row": 9
646
+ },
647
+ "end": {
648
+ "column": 6,
649
+ "row": 7
650
+ }
651
+ },
652
+ "lisp": {
653
+ "start": {
654
+ "column": 3,
655
+ "row": 6
656
+ },
657
+ "end": {
658
+ "column": 6,
659
+ "row": 3
660
+ }
661
+ },
662
+ "ruby": {
663
+ "start": {
664
+ "column": 8,
665
+ "row": 6
666
+ },
667
+ "end": {
668
+ "column": 5,
669
+ "row": 9
670
+ }
671
+ },
672
+ "haskell": null
673
+ }
674
+ }
675
+ ]
676
+ }
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.1.0.3"
2
+ VERSION = "2.1.0.4"
3
3
  end
@@ -7,9 +7,11 @@ type
7
7
  ['{2415B863-E2D7-4E13-BDEF-F7FE9B3E0788}']
8
8
  function GetCleanNumber: string;
9
9
  function GetAreaCode: string;
10
+ function GetExchangeCode: string;
10
11
  function ToString: string;
11
12
  property Clean: string read GetCleanNumber;
12
- property AreaCode: string read GetAreaCode;
13
+ property Area: string read GetAreaCode;
14
+ property Exchange: string read GetExchangeCode;
13
15
  end;
14
16
 
15
17
  function NewPhoneNumber(aPhoneNumber: string): IPhoneNumber;
@@ -24,18 +26,22 @@ type
24
26
  fContainsLetters: TRegex;
25
27
  fNumber: string;
26
28
  fAreaCode: string;
29
+ fExchangeCode: string;
27
30
  function GetCleanNumber: string;
28
31
  function GetAreaCode: string;
32
+ function GetExchangeCode: string;
29
33
  function GetValidatedPhoneNumber(aPhoneNumber: string): string;
30
34
  function StripOutNonNumerics(aValue: string): string;
31
35
  function IsInvalidPhoneNumber(aPhoneNumber: string): Boolean;
32
36
  function GetInvalidPhoneNumberReplacement(aPhoneNumber: string): string;
33
37
  function IsPhoneNumberwithUSAreaCode(aValue: string): Boolean;
38
+ function IsValidCode(aCode: string): Boolean;
34
39
  public
35
40
  constructor Create(aPhoneNumber: string);
36
41
  function ToString: string;
37
42
  property Clean: string read GetCleanNumber;
38
- property AreaCode: string read GetAreaCode;
43
+ property Area: string read GetAreaCode;
44
+ property Exchange: string read GetExchangeCode;
39
45
  end;
40
46
 
41
47
  function NewPhoneNumber(aPhoneNumber: string): IPhoneNumber;
@@ -48,17 +54,26 @@ begin
48
54
  fDigitsOnly := TRegEx.Create('[^\d]');
49
55
  fContainsLetters := TRegEx.Create('[a-zA-Z]');
50
56
  fNumber := GetValidatedPhoneNumber(aPhoneNumber);
51
- fAreaCode := fNumber.Substring(0, 3);
57
+ if not fNumber.IsEmpty then
58
+ begin
59
+ fAreaCode := fNumber.Substring(0, 3);
60
+ fExchangeCode := fNumber.Substring(3,3);
61
+ end;
52
62
  end;
53
63
 
54
64
  function TPhoneNumber.GetCleanNumber: string;
55
65
  begin
56
- result := fNumber;
66
+ result := ifthen(IsValidCode(fAreaCode) and IsValidCode(fExchangeCode),fNumber,'');
57
67
  end;
58
68
 
59
69
  function TPhoneNumber.GetAreaCode: string;
60
70
  begin
61
- result := fAreaCode;
71
+ result := ifthen(IsValidCode(fAreaCode),fAreaCode,'');
72
+ end;
73
+
74
+ function TPhoneNumber.GetExchangeCode: string;
75
+ begin
76
+ result := ifthen(IsValidCode(fExchangeCode),fExchangeCode,'');
62
77
  end;
63
78
 
64
79
  function TPhoneNumber.GetValidatedPhoneNumber(aPhoneNumber: string):string;
@@ -94,9 +109,14 @@ begin
94
109
  result := (aValue.Length = 11) and aValue.StartsWith('1');
95
110
  end;
96
111
 
112
+ function TPhoneNumber.IsValidCode(aCode: string): Boolean;
113
+ begin
114
+ result := (not aCode.IsEmpty) and (aCode[1] in ['2'..'9']);
115
+ end;
116
+
97
117
  function TPhoneNumber.ToString: string;
98
118
  begin
99
- result := Format('(%s) %s-%s',[AreaCode, Clean.Substring(3, 3), Clean.Substring(6)]);
119
+ result := Format('(%s) %s-%s',[Area, Exchange, Clean.Substring(6)]);
100
120
  end;
101
121
 
102
122
  end.
@@ -16,7 +16,7 @@ type
16
16
  PhoneNumberTests = class(TObject)
17
17
  public
18
18
  [Test]
19
- // [Ignore('Comment the "[Ignore]" statement to run the test')]
19
+ // [Ignore('Comment the "[Ignore]" statement to run the test')]
20
20
  procedure Cleans_the_number;
21
21
 
22
22
  [Test]
@@ -55,9 +55,21 @@ type
55
55
  [Ignore]
56
56
  procedure Invalid_with_right_number_of_digits_but_letters_mixed_in;
57
57
 
58
+ [Test]
59
+ [Ignore]
60
+ procedure Invalid_if_area_code_does_not_start_with_2_thru_9;
61
+
62
+ [Test]
63
+ [Ignore]
64
+ procedure Invalid_if_exchange_code_does_not_start_with_2_thru_9;
65
+
58
66
  [Test]
59
67
  [Ignore('This is a bonus test')]
60
- procedure Has_an_area_code;
68
+ procedure Extract_area_code;
69
+
70
+ [Test]
71
+ [Ignore('This is a bonus test')]
72
+ procedure Extract_exchange_code;
61
73
 
62
74
  [Test]
63
75
  [Ignore('This is a bonus test')]
@@ -70,35 +82,35 @@ uses uPhoneNumber;
70
82
  procedure PhoneNumberTests.Cleans_the_number;
71
83
  var phone: IPhoneNumber;
72
84
  begin
73
- phone := NewPhoneNumber('(123) 456-7890');
74
- assert.AreEqual('1234567890',phone.Clean);
85
+ phone := NewPhoneNumber('(223) 456-7890');
86
+ assert.AreEqual('2234567890',phone.Clean);
75
87
  end;
76
88
 
77
89
  procedure PhoneNumberTests.Cleans_numbers_with_dots;
78
90
  var phone: IPhoneNumber;
79
91
  begin
80
- phone := NewPhoneNumber('123.456.7890');
81
- assert.AreEqual('1234567890',phone.Clean);
92
+ phone := NewPhoneNumber('223.456.7890');
93
+ assert.AreEqual('2234567890',phone.Clean);
82
94
  end;
83
95
 
84
96
  procedure PhoneNumberTests.Cleans_numbers_with_multiple_spaces;
85
97
  var phone: IPhoneNumber;
86
98
  begin
87
- phone := NewPhoneNumber('123 456 7890 ');
88
- assert.AreEqual('1234567890',phone.Clean);
99
+ phone := NewPhoneNumber('223 456 7890 ');
100
+ assert.AreEqual('2234567890',phone.Clean);
89
101
  end;
90
102
 
91
103
  procedure PhoneNumberTests.Valid_when_11_digits_and_starting_with_1;
92
104
  var phone: IPhoneNumber;
93
105
  begin
94
- phone := NewPhoneNumber('11234567890');
95
- assert.AreEqual('1234567890', phone.Clean);
106
+ phone := NewPhoneNumber('12234567890');
107
+ assert.AreEqual('2234567890', phone.Clean);
96
108
  end;
97
109
 
98
110
  procedure PhoneNumberTests.Invalid_when_11_digits_does_not_start_with_a_1;
99
111
  var phone: IPhoneNumber;
100
112
  begin
101
- phone := NewPhoneNumber('21234567890');
113
+ phone := NewPhoneNumber('22234567890');
102
114
  assert.AreEqual('', phone.Clean);
103
115
  end;
104
116
 
@@ -137,18 +149,39 @@ begin
137
149
  assert.AreEqual('', phone.Clean);
138
150
  end;
139
151
 
140
- procedure PhoneNumberTests.Has_an_area_code;
152
+ procedure PhoneNumberTests.Invalid_if_area_code_does_not_start_with_2_thru_9;
153
+ var phone: IPhoneNumber;
154
+ begin
155
+ phone := NewPhoneNumber('(123) 456-7890');
156
+ assert.AreEqual('', phone.Clean);
157
+ end;
158
+
159
+ procedure PhoneNumberTests.Invalid_if_exchange_code_does_not_start_with_2_thru_9;
160
+ var phone: IPhoneNumber;
161
+ begin
162
+ phone := NewPhoneNumber('(223) 056-7890');
163
+ assert.AreEqual('', phone.Clean);
164
+ end;
165
+
166
+ procedure PhoneNumberTests.Extract_area_code;
167
+ var phone: IPhoneNumber;
168
+ begin
169
+ phone := NewPhoneNumber('(223) 456-7890');
170
+ assert.AreEqual('223', phone.Area);
171
+ end;
172
+
173
+ procedure PhoneNumberTests.Extract_exchange_code;
141
174
  var phone: IPhoneNumber;
142
175
  begin
143
- phone := NewPhoneNumber('1234567890');
144
- assert.AreEqual('123', phone.AreaCode);
176
+ phone := NewPhoneNumber('223.456.7890');
177
+ assert.AreEqual('456', phone.Exchange);
145
178
  end;
146
179
 
147
180
  procedure PhoneNumberTests.Formats_a_number;
148
181
  var phone: IPhoneNumber;
149
182
  begin
150
- phone := NewPhoneNumber('1234567890');
151
- assert.AreEqual('(123) 456-7890', phone.ToString);
183
+ phone := NewPhoneNumber('2234567890');
184
+ assert.AreEqual('(223) 456-7890', phone.ToString);
152
185
  end;
153
186
 
154
187
  initialization
@@ -49,9 +49,6 @@ const (
49
49
  // Header tells how the test data was generated, for display in the header of
50
50
  // cases_test.go
51
51
  type Header struct {
52
- // Ori is a deprecated short name for Origin.
53
- // TODO: Remove Ori once everything switches to Origin.
54
- Ori string
55
52
  Origin string
56
53
  Commit string
57
54
  Version string
@@ -126,7 +123,6 @@ func Gen(exercise string, j interface{}, t *template.Template) error {
126
123
  Header
127
124
  J interface{}
128
125
  }{Header{
129
- Ori: jOrigin,
130
126
  Origin: jOrigin,
131
127
  Commit: jCommit,
132
128
  Version: commonMetadata.Version,
@@ -3,56 +3,110 @@ gem 'minitest', '>= 5.0.0'
3
3
  require 'minitest/autorun'
4
4
  require_relative 'etl'
5
5
 
6
- class TransformTest < Minitest::Test
7
- def test_transform_one_value
8
- old = { 1 => ['A'] }
9
- expected = { 'a' => 1 }
10
-
6
+ # Common test data version: ca9ed58
7
+ class EtlTest < Minitest::Test
8
+ def test_a_single_letter
9
+ # skip
10
+ old = {
11
+ 1 => ["A"]
12
+ }
13
+ expected = {
14
+ 'a' => 1
15
+ }
11
16
  assert_equal expected, ETL.transform(old)
12
17
  end
13
18
 
14
- def test_transform_more_values
19
+ def test_single_score_with_multiple_letters
15
20
  skip
16
- old = { 1 => %w(A E I O U) }
17
- expected = { 'a' => 1, 'e' => 1, 'i' => 1, 'o' => 1, 'u' => 1 }
18
-
21
+ old = {
22
+ 1 => ["A", "E", "I", "O", "U"]
23
+ }
24
+ expected = {
25
+ 'a' => 1,
26
+ 'e' => 1,
27
+ 'i' => 1,
28
+ 'o' => 1,
29
+ 'u' => 1
30
+ }
19
31
  assert_equal expected, ETL.transform(old)
20
32
  end
21
33
 
22
- def test_more_keys
34
+ def test_multiple_scores_with_multiple_letters
23
35
  skip
24
- old = { 1 => %w(A E), 2 => %w(D G) }
36
+ old = {
37
+ 1 => ["A", "E"],
38
+ 2 => ["D", "G"]
39
+ }
25
40
  expected = {
26
41
  'a' => 1,
27
- 'e' => 1,
28
42
  'd' => 2,
43
+ 'e' => 1,
29
44
  'g' => 2
30
45
  }
31
-
32
46
  assert_equal expected, ETL.transform(old)
33
47
  end
34
48
 
35
- def test_full_dataset
49
+ def test_multiple_scores_with_differing_numbers_of_letters
36
50
  skip
37
51
  old = {
38
- 1 => %w(A E I O U L N R S T),
39
- 2 => %w(D G),
40
- 3 => %w(B C M P),
41
- 4 => %w(F H V W Y),
42
- 5 => %w(K),
43
- 8 => %w(J X),
44
- 10 => %w(Q Z)
52
+ 1 => ["A", "E", "I", "O", "U", "L", "N", "R", "S", "T"],
53
+ 2 => ["D", "G"],
54
+ 3 => ["B", "C", "M", "P"],
55
+ 4 => ["F", "H", "V", "W", "Y"],
56
+ 5 => ["K"],
57
+ 8 => ["J", "X"],
58
+ 10 => ["Q", "Z"]
45
59
  }
46
-
47
60
  expected = {
48
- 'a' => 1, 'b' => 3, 'c' => 3, 'd' => 2, 'e' => 1,
49
- 'f' => 4, 'g' => 2, 'h' => 4, 'i' => 1, 'j' => 8,
50
- 'k' => 5, 'l' => 1, 'm' => 3, 'n' => 1, 'o' => 1,
51
- 'p' => 3, 'q' => 10, 'r' => 1, 's' => 1, 't' => 1,
52
- 'u' => 1, 'v' => 4, 'w' => 4, 'x' => 8, 'y' => 4,
61
+ 'a' => 1,
62
+ 'b' => 3,
63
+ 'c' => 3,
64
+ 'd' => 2,
65
+ 'e' => 1,
66
+ 'f' => 4,
67
+ 'g' => 2,
68
+ 'h' => 4,
69
+ 'i' => 1,
70
+ 'j' => 8,
71
+ 'k' => 5,
72
+ 'l' => 1,
73
+ 'm' => 3,
74
+ 'n' => 1,
75
+ 'o' => 1,
76
+ 'p' => 3,
77
+ 'q' => 10,
78
+ 'r' => 1,
79
+ 's' => 1,
80
+ 't' => 1,
81
+ 'u' => 1,
82
+ 'v' => 4,
83
+ 'w' => 4,
84
+ 'x' => 8,
85
+ 'y' => 4,
53
86
  'z' => 10
54
87
  }
55
-
56
88
  assert_equal expected, ETL.transform(old)
57
89
  end
90
+
91
+ # Problems in exercism evolve over time, as we find better ways to ask
92
+ # questions.
93
+ # The version number refers to the version of the problem you solved,
94
+ # not your solution.
95
+ #
96
+ # Define a constant named VERSION inside of the top level BookKeeping
97
+ # module, which may be placed near the end of your file.
98
+ #
99
+ # In your file, it will look like this:
100
+ #
101
+ # module BookKeeping
102
+ # VERSION = 1 # Where the version number matches the one in the test.
103
+ # end
104
+ #
105
+ # If you are curious, read more about constants on RubyDoc:
106
+ # http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
107
+
108
+ def test_bookkeeping
109
+ skip
110
+ assert_equal 1, BookKeeping::VERSION
111
+ end
58
112
  end
@@ -1,3 +1,7 @@
1
+ module BookKeeping
2
+ VERSION = 1
3
+ end
4
+
1
5
  class ETL
2
6
  def self.transform(old)
3
7
  data = {}
@@ -0,0 +1,28 @@
1
+ require 'generator/exercise_cases'
2
+
3
+ class EtlCase < ExerciseCase
4
+ def workload
5
+ indent_lines([
6
+ "old = {\n #{format(input)}\n }",
7
+ "expected = {\n #{format(expected)}\n }",
8
+ "assert_equal expected, ETL.transform(old)"
9
+ ], 4)
10
+ end
11
+
12
+ private
13
+
14
+ def format(obj)
15
+ case
16
+ when obj.respond_to?(:each_pair)
17
+ indent_lines(
18
+ obj.each_with_object([]) {|(k, v), string| string << "#{format(k)} => #{format(v)}" },
19
+ 6,
20
+ ",\n"
21
+ )
22
+ when obj.respond_to?(:each) then obj
23
+ when obj.to_s =~ /\d+/ then obj.to_i
24
+ else %Q('#{obj}')
25
+ end
26
+ end
27
+
28
+ end
@@ -21,8 +21,8 @@ class ExerciseCase < OpenStruct
21
21
  # "#{assert} Isogram.is_isogram?(string)"
22
22
  # ], 4
23
23
  # )
24
- def indent_lines(code, depth)
25
- code.join("\n" + ' ' * depth)
24
+ def indent_lines(code, depth, separator = "\n")
25
+ code.join(separator + ' ' * depth)
26
26
  end
27
27
 
28
28
  # used in workload, for example, as
@@ -1,25 +1,24 @@
1
1
  struct GradeSchool {
2
- var roster = [Int: Set<String>]()
2
+ var roster = [Int: [String]]()
3
3
 
4
4
  mutating func addStudent(_ name: String, grade: Int) {
5
5
  if let students = roster[grade] {
6
6
  var students = students
7
- students.insert(name)
7
+ students.append(name)
8
8
  roster[grade] = students
9
9
  } else {
10
- roster[grade] = Set(arrayLiteral: name)
10
+ roster[grade] = [name]
11
11
  }
12
12
  }
13
13
 
14
- func studentsInGrade(_ grade: Int) -> Set<String> {
15
- return roster[grade] ?? Set<String>()
14
+ func studentsInGrade(_ grade: Int) -> [String] {
15
+ return roster[grade] ?? [String]()
16
16
  }
17
17
 
18
- var sortedRoster: [Int: Set<String>] {
19
- var sortedRoster = [Int: Set<String>](minimumCapacity: roster.count)
18
+ var sortedRoster: [Int: [String]] {
19
+ var sortedRoster = [Int: [String]](minimumCapacity: roster.count)
20
20
  for (grade, students) in roster {
21
- sortedRoster[grade] = Set(students.sorted())
22
-
21
+ sortedRoster[grade] = students.sorted()
23
22
  }
24
23
  return sortedRoster
25
24
  }
@@ -3,27 +3,19 @@ import XCTest
3
3
 
4
4
  class GradeSchoolTests: XCTestCase {
5
5
 
6
- // Workaround unit test liminitaiton on Optional Arrays/Sets
7
- private func sameCollection<C: Collection>(_ result: C?, _ expected: [String]?) -> Bool where C.Iterator.Element == String {
8
- guard let result = result, let expected = expected, similar(result, expected) else { return false }
9
- for (index, student) in result.enumerated() {
10
- guard index < expected.count && expected.contains(student) else { return false }
11
- }
12
- return true
13
- }
14
- private func similar<C: Collection>(_ result: C, _ expected: [String]) -> Bool {
15
- return result.count.toIntMax() == IntMax(expected.count)
6
+ func sameArray(_ result: [String]?, _ expected: [String]? ) -> Bool {
7
+ guard let result = result, let expected = expected else { return false }
8
+ return result == expected
16
9
  }
17
10
 
18
- func XCTAssertEqualCollection<C:Collection> (_ collectionS: C?, _ collectionA: [String]? ) where C.Iterator.Element == String {
19
- XCTAssert(sameCollection(collectionS, collectionA))
11
+ func XCTAssertEqualArray (_ result: [String]?, _ expected: [String]? ) {
12
+ XCTAssertTrue(sameArray(expected, result))
20
13
  }
21
14
 
22
15
  func testAnEmptySchool() {
23
16
  let school = GradeSchool()
24
17
  let result = school.roster
25
18
  XCTAssertTrue(result.isEmpty)
26
-
27
19
  }
28
20
 
29
21
  func testAddStudent() {
@@ -32,7 +24,7 @@ class GradeSchoolTests: XCTestCase {
32
24
  let result = school.roster
33
25
  let expected: Dictionary = [2: ["Aimee"]]
34
26
  XCTAssertEqual(Array(result.keys), Array(expected.keys))
35
- XCTAssertEqualCollection(result[2], expected[2])
27
+ XCTAssertEqualArray(result[2], expected[2])
36
28
  }
37
29
 
38
30
  func testAddMoreStudentsInSameClass() {
@@ -43,7 +35,7 @@ class GradeSchoolTests: XCTestCase {
43
35
  let result = school.roster
44
36
  let expected = [2: ["Fred", "James", "Paul"]]
45
37
  XCTAssertEqual(Array(result.keys), Array(expected.keys))
46
- XCTAssertEqualCollection(result[2], expected[2])
38
+ XCTAssertEqualArray(result[2], expected[2])
47
39
  }
48
40
 
49
41
  func testAddStudentsToDifferentGrades() {
@@ -54,7 +46,7 @@ class GradeSchoolTests: XCTestCase {
54
46
  let expected = [3: ["Chelsea"], 7: ["Logan"]]
55
47
  XCTAssertEqual(Array(result.keys).sorted(by: >), Array(expected.keys).sorted(by: >))
56
48
 
57
- XCTAssertEqualCollection(result[3], expected[3])
49
+ XCTAssertEqualArray(result[3], expected[3])
58
50
  }
59
51
 
60
52
  func testGetStudentsInAGrade() {
@@ -64,7 +56,7 @@ class GradeSchoolTests: XCTestCase {
64
56
  school.addStudent("Jeff", grade: 1)
65
57
  let result = school.studentsInGrade(5)
66
58
  let expected = ["Franklin", "Bradley"]
67
- XCTAssertEqualCollection(result, expected)
59
+ XCTAssertEqual(result, expected)
68
60
  }
69
61
 
70
62
  func testGetStudentsInANonExistantGrade() {
@@ -72,7 +64,7 @@ class GradeSchoolTests: XCTestCase {
72
64
  let result = school.studentsInGrade(1)
73
65
 
74
66
  let expected = [String]()
75
- XCTAssertEqualCollection(result, expected)
67
+ XCTAssertEqual(result, expected)
76
68
  }
77
69
 
78
70
  func testSortSchool() {
@@ -88,11 +80,12 @@ class GradeSchoolTests: XCTestCase {
88
80
  4: ["Christopher", "Jennifer"],
89
81
  6: ["Kareem"]
90
82
  ]
83
+
91
84
  XCTAssertEqual(Array(result.keys).sorted(by: >), Array(expected.keys).sorted(by: >))
92
85
 
93
- XCTAssertEqualCollection(result[3], expected[3])
94
- XCTAssertEqualCollection(result[4], expected[4])
95
- XCTAssertEqualCollection(result[6], expected[6])
86
+ XCTAssertEqualArray(result[3], expected[3])
87
+ XCTAssertEqualArray(result[4], expected[4])
88
+ XCTAssertEqualArray(result[6], expected[6])
96
89
  }
97
90
 
98
91
  static var allTests: [(String, (GradeSchoolTests) -> () throws -> Void)] {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trackler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0.3
4
+ version: 2.1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katrina Owen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-28 00:00:00.000000000 Z
11
+ date: 2017-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -414,6 +414,7 @@ files:
414
414
  - common/exercises/word-count/canonical-data.json
415
415
  - common/exercises/word-count/description.md
416
416
  - common/exercises/word-count/metadata.yml
417
+ - common/exercises/word-search/canonical-data.json
417
418
  - common/exercises/word-search/description.md
418
419
  - common/exercises/word-search/metadata.yml
419
420
  - common/exercises/wordy/canonical-data.json
@@ -7227,6 +7228,7 @@ files:
7227
7228
  - tracks/ruby/exercises/dominoes/dominoes_test.rb
7228
7229
  - tracks/ruby/exercises/dominoes/example.rb
7229
7230
  - tracks/ruby/exercises/dominoes/example.tt
7231
+ - tracks/ruby/exercises/etl/.meta/.version
7230
7232
  - tracks/ruby/exercises/etl/etl_test.rb
7231
7233
  - tracks/ruby/exercises/etl/example.rb
7232
7234
  - tracks/ruby/exercises/flatten-array/example.rb
@@ -7405,6 +7407,7 @@ files:
7405
7407
  - tracks/ruby/lib/difference_of_squares_cases.rb
7406
7408
  - tracks/ruby/lib/disable_skip.rb
7407
7409
  - tracks/ruby/lib/dominoes_cases.rb
7410
+ - tracks/ruby/lib/etl_cases.rb
7408
7411
  - tracks/ruby/lib/generator.rb
7409
7412
  - tracks/ruby/lib/generator/case_values.rb
7410
7413
  - tracks/ruby/lib/generator/command_line.rb