trackler 2.0.3.4 → 2.0.3.5
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 +4 -4
- data/common/exercises/all-your-base/canonical-data.json +21 -21
- data/common/exercises/wordy/description.md +24 -38
- data/common/exercises/wordy/metadata.yml +1 -1
- data/lib/trackler/version.rb +1 -1
- data/tracks/c/config.json +10 -0
- data/tracks/c/exercises/meetup/makefile +15 -0
- data/tracks/c/exercises/meetup/src/example.c +139 -0
- data/tracks/c/exercises/meetup/src/example.h +7 -0
- data/tracks/c/exercises/meetup/test/test_meetup.c +223 -0
- data/tracks/c/exercises/meetup/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/meetup/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/meetup/test/vendor/unity_internals.h +701 -0
- data/tracks/crystal/config.json +12 -0
- data/tracks/crystal/exercises/pascals-triangle/spec/pascals_triangle_spec.cr +30 -0
- data/tracks/crystal/exercises/pascals-triangle/src/example.cr +19 -0
- data/tracks/crystal/exercises/pascals-triangle/src/pascals_triangle.cr +1 -0
- data/tracks/crystal/exercises/run-length-encoding/spec/run_length_encoding_spec.cr +36 -0
- data/tracks/crystal/exercises/run-length-encoding/src/example.cr +40 -0
- data/tracks/crystal/src/generator/exercises/pascals-triangle.cr +58 -0
- data/tracks/crystal/src/generator/exercises/run_length_encoding.cr +42 -0
- data/tracks/javascript/config.json +8 -1
- data/tracks/javascript/exercises/all-your-base/all-your-base.spec.js +141 -0
- data/tracks/javascript/exercises/all-your-base/example.js +59 -0
- data/tracks/javascript/exercises/word-count/example.js +5 -5
- data/tracks/javascript/exercises/word-count/word-count.spec.js +23 -8
- data/tracks/lua/SETUP.md +60 -7
- data/tracks/lua/config.json +9 -0
- data/tracks/lua/exercises/say/example.lua +4 -4
- data/tracks/lua/exercises/variable-length-quantity/example.lua +36 -0
- data/tracks/lua/exercises/variable-length-quantity/variable-length-quantity_spec.lua +73 -0
- data/tracks/objective-c/.travis.yml +1 -0
- data/tracks/objective-c/config.json +8 -0
- data/tracks/objective-c/docs/TESTS.md +1 -1
- data/tracks/objective-c/exercises/transpose/TransposeExample.h +7 -0
- data/tracks/objective-c/exercises/transpose/TransposeExample.m +59 -0
- data/tracks/objective-c/exercises/transpose/TransposeTest.m +150 -0
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
- data/tracks/ocaml/.gitignore +1 -0
- data/tracks/ocaml/tools/test-generator/Makefile +3 -0
- data/tracks/ocaml/tools/test-generator/src/controller.ml +11 -16
- data/tracks/ocaml/tools/test-generator/src/model.ml +4 -0
- data/tracks/ocaml/tools/test-generator/src/parser.ml +8 -1
- data/tracks/ocaml/tools/test-generator/src/special_cases.ml +5 -0
- data/tracks/ocaml/tools/test-generator/templates/all-your-base/template.ml +16 -0
- data/tracks/ocaml/tools/test-generator/test/model_test.ml +2 -0
- data/tracks/ocaml/tools/test-generator/test/parser_test.ml +8 -0
- data/tracks/perl5/docs/RESOURCES.md +57 -0
- data/tracks/perl5/exercises/hamming/Example.pm +7 -0
- data/tracks/perl5/exercises/hamming/hamming.t +17 -4
- data/tracks/perl5/exercises/rna-transcription/rna.t +4 -4
- data/tracks/perl6/.gitignore +2 -0
- data/tracks/perl6/config.json +5 -0
- data/tracks/perl6/exercises/phone-number/Example.pm +30 -0
- data/tracks/perl6/exercises/phone-number/cases.json +47 -0
- data/tracks/perl6/exercises/phone-number/phone.t +48 -0
- data/tracks/purescript/.gitignore +8 -0
- data/tracks/purescript/config.json +8 -3
- data/tracks/purescript/exercises/hello-world/bower.json +17 -0
- data/tracks/purescript/exercises/hello-world/examples/src/HelloWorld.purs +8 -0
- data/tracks/purescript/exercises/hello-world/src/HelloWorld.purs +6 -0
- data/tracks/purescript/exercises/hello-world/test/Main.purs +18 -0
- data/tracks/scala/exercises/leap/HINTS.md +4 -0
- data/tracks/scala/exercises/robot-name/HINTS.md +5 -0
- data/tracks/swift/docs/INSTALLATION.md +4 -1
- data/tracks/swift/exercises/accumulate/AccumulateTest.swift +1 -1
- data/tracks/swift/exercises/binary/BinaryExample.swift +4 -1
- data/tracks/swift/exercises/crypto-square/CryptoSquareExample.swift +3 -2
- data/tracks/swift/exercises/leap/LeapExample.swift +1 -3
- data/tracks/swift/exercises/pascals-triangle/PascalsTriangleTest.swift +1 -1
- data/tracks/swift/exercises/poker/PokerExample.swift +3 -3
- data/tracks/swift/exercises/poker/PokerTest.swift +38 -38
- data/tracks/swift/exercises/saddle-points/SaddlePointsTest.swift +1 -1
- data/tracks/swift/exercises/scrabble-score/ScrabbleScoreExample.swift +6 -3
- data/tracks/swift/exercises/series/SeriesTest.swift +1 -1
- data/tracks/swift/exercises/simple-linked-list/SimpleLinkedListExample.swift +2 -2
- data/tracks/swift/exercises/space-age/SpaceAgeExample.swift +10 -12
- data/tracks/swift/exercises/strain/StrainTest.swift +1 -1
- data/tracks/swift/exercises/tournament/TournamentExample.swift +2 -2
- data/tracks/swift/exercises/triangle/TriangleExample.swift +7 -3
- data/tracks/swift/exercises/wordy/WordyExample.swift +1 -2
- metadata +34 -3
- data/tracks/purescript/exercises/.keep +0 -0
@@ -65,6 +65,8 @@
|
|
65
65
|
E94ACA151D41763800D56CC2 /* AllYourBaseTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E94ACA141D41763800D56CC2 /* AllYourBaseTest.m */; };
|
66
66
|
E951B6B71D4294E6009EB5B6 /* AllergiesExample.m in Sources */ = {isa = PBXBuildFile; fileRef = E951B6B61D4294E6009EB5B6 /* AllergiesExample.m */; };
|
67
67
|
E951B6B91D429550009EB5B6 /* AllergiesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E951B6B81D429550009EB5B6 /* AllergiesTest.m */; };
|
68
|
+
E96993981DF60E1E009EA223 /* TransposeExample.m in Sources */ = {isa = PBXBuildFile; fileRef = E96993971DF60E1E009EA223 /* TransposeExample.m */; };
|
69
|
+
E969939A1DF60E5F009EA223 /* TransposeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E96993991DF60E5F009EA223 /* TransposeTest.m */; };
|
68
70
|
E99D1D811D5533BF0006A303 /* SumOfMultiplesExample.m in Sources */ = {isa = PBXBuildFile; fileRef = E99D1D801D5533BF0006A303 /* SumOfMultiplesExample.m */; };
|
69
71
|
E99D1D831D5533D80006A303 /* SumOfMultiplesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E99D1D821D5533D80006A303 /* SumOfMultiplesTest.m */; };
|
70
72
|
E9A7B2F71DA5AC37009056B6 /* LargestSeriesProductExample.m in Sources */ = {isa = PBXBuildFile; fileRef = E9A7B2F61DA5AC37009056B6 /* LargestSeriesProductExample.m */; };
|
@@ -150,6 +152,9 @@
|
|
150
152
|
E951B6B51D4294E6009EB5B6 /* AllergiesExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AllergiesExample.h; path = ../../exercises/allergies/AllergiesExample.h; sourceTree = "<group>"; };
|
151
153
|
E951B6B61D4294E6009EB5B6 /* AllergiesExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AllergiesExample.m; path = ../../exercises/allergies/AllergiesExample.m; sourceTree = "<group>"; };
|
152
154
|
E951B6B81D429550009EB5B6 /* AllergiesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AllergiesTest.m; path = ../../exercises/allergies/AllergiesTest.m; sourceTree = "<group>"; };
|
155
|
+
E96993961DF60E1E009EA223 /* TransposeExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TransposeExample.h; path = ../../exercises/transpose/TransposeExample.h; sourceTree = "<group>"; };
|
156
|
+
E96993971DF60E1E009EA223 /* TransposeExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TransposeExample.m; path = ../../exercises/transpose/TransposeExample.m; sourceTree = "<group>"; };
|
157
|
+
E96993991DF60E5F009EA223 /* TransposeTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TransposeTest.m; path = ../../exercises/transpose/TransposeTest.m; sourceTree = "<group>"; };
|
153
158
|
E99D1D7F1D5533BF0006A303 /* SumOfMultiplesExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SumOfMultiplesExample.h; path = "../../exercises/sum-of-multiples/SumOfMultiplesExample.h"; sourceTree = "<group>"; };
|
154
159
|
E99D1D801D5533BF0006A303 /* SumOfMultiplesExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SumOfMultiplesExample.m; path = "../../exercises/sum-of-multiples/SumOfMultiplesExample.m"; sourceTree = "<group>"; };
|
155
160
|
E99D1D821D5533D80006A303 /* SumOfMultiplesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SumOfMultiplesTest.m; path = "../../exercises/sum-of-multiples/SumOfMultiplesTest.m"; sourceTree = "<group>"; };
|
@@ -214,6 +219,7 @@
|
|
214
219
|
E9C1C0201D9D98B80015E86E /* SecretHandshake */,
|
215
220
|
E9E8B6F61D519E340012F12C /* SpaceAge */,
|
216
221
|
E99D1D7B1D5532C50006A303 /* SumOfMultiples */,
|
222
|
+
E96993951DF60DF1009EA223 /* Transpose */,
|
217
223
|
E947A4DB1D81FDDA00633720 /* Triangle */,
|
218
224
|
E9E8B6F71D519E3A0012F12C /* WordCount */,
|
219
225
|
1E50BD001CB465C500FC128D /* Info.plist */,
|
@@ -307,6 +313,16 @@
|
|
307
313
|
name = Triangle;
|
308
314
|
sourceTree = "<group>";
|
309
315
|
};
|
316
|
+
E96993951DF60DF1009EA223 /* Transpose */ = {
|
317
|
+
isa = PBXGroup;
|
318
|
+
children = (
|
319
|
+
E96993961DF60E1E009EA223 /* TransposeExample.h */,
|
320
|
+
E96993971DF60E1E009EA223 /* TransposeExample.m */,
|
321
|
+
E96993991DF60E5F009EA223 /* TransposeTest.m */,
|
322
|
+
);
|
323
|
+
name = Transpose;
|
324
|
+
sourceTree = "<group>";
|
325
|
+
};
|
310
326
|
E99D1D7B1D5532C50006A303 /* SumOfMultiples */ = {
|
311
327
|
isa = PBXGroup;
|
312
328
|
children = (
|
@@ -617,6 +633,7 @@
|
|
617
633
|
1EFACAA31CCCAF3D006F2E69 /* AnagramExample.m in Sources */,
|
618
634
|
E94ACA131D41760300D56CC2 /* AllYourBaseExample.m in Sources */,
|
619
635
|
E94ACA151D41763800D56CC2 /* AllYourBaseTest.m in Sources */,
|
636
|
+
E96993981DF60E1E009EA223 /* TransposeExample.m in Sources */,
|
620
637
|
E9C1C0291D9DB16B0015E86E /* AcronymExample.m in Sources */,
|
621
638
|
1EFACAA41CCCAF3D006F2E69 /* AnagramTest.m in Sources */,
|
622
639
|
E907FE921D87547D00B93DA9 /* ScrabbleScoreExample.m in Sources */,
|
@@ -669,6 +686,7 @@
|
|
669
686
|
E9A7B2F91DA5AC55009056B6 /* LargestSeriesProductTest.m in Sources */,
|
670
687
|
1EFACAAF1CCCAF3D006F2E69 /* LeapExample.m in Sources */,
|
671
688
|
E9C1C0251D9D99620015E86E /* SecretHandshakeTest.m in Sources */,
|
689
|
+
E969939A1DF60E5F009EA223 /* TransposeTest.m in Sources */,
|
672
690
|
E99D1D831D5533D80006A303 /* SumOfMultiplesTest.m in Sources */,
|
673
691
|
1EFACAAA1CCCAF3D006F2E69 /* GradeSchoolTest.m in Sources */,
|
674
692
|
);
|
data/tracks/ocaml/.gitignore
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
test: test_gen.native
|
2
2
|
@./all_tests.native
|
3
3
|
|
4
|
+
test_gen.byte: all_tests.native src/*.ml interfaces/*.mli test/*.ml
|
5
|
+
@ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces test_gen.byte
|
6
|
+
|
4
7
|
test_gen.native: all_tests.native src/*.ml interfaces/*.mli test/*.ml
|
5
8
|
@ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces test_gen.native
|
6
9
|
|
@@ -23,26 +23,21 @@ let combine_files (template_files: (string * content) list) (canonical_data_file
|
|
23
23
|
|
24
24
|
let generate_code ~(slug: string) ~(template_file: content) ~(canonical_data_file: content): (content, content) Result.t =
|
25
25
|
let template = find_template template_file in
|
26
|
+
let edit_expected = edit_expected ~stringify:parameter_to_string ~slug in
|
27
|
+
let edit_parameters = edit_parameters ~slug in
|
28
|
+
let fill_in_template = fill_in_template edit_expected edit_parameters in
|
26
29
|
let open Result.Monad_infix in
|
27
30
|
Result.of_option template ("cannot recognize file for " ^ slug ^ " as a template") >>= fun template ->
|
28
|
-
parse_json_text canonical_data_file
|
31
|
+
parse_json_text canonical_data_file
|
32
|
+
|> Result.map_error ~f:show_error >>= (function
|
29
33
|
| Single cases ->
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
template.template
|
34
|
-
slug
|
35
|
-
cases |> fill_tests template);
|
34
|
+
fill_in_template template.template slug cases
|
35
|
+
|> fill_tests template
|
36
|
+
|> Result.return
|
36
37
|
| Suite tests ->
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
(edit_parameters ~slug)
|
41
|
-
template.template
|
42
|
-
name
|
43
|
-
cases)
|
44
|
-
) in
|
45
|
-
Result.return (fill_suite template x)
|
38
|
+
List.map tests ~f:(fun {name;cases} -> (name, fill_in_template template.template name cases))
|
39
|
+
|> fill_suite template
|
40
|
+
|> Result.return
|
46
41
|
)
|
47
42
|
|
48
43
|
let output_tests (files: (string * content * content) list) (output_folder: string): unit =
|
@@ -3,11 +3,13 @@ open Core.Std
|
|
3
3
|
open Utils
|
4
4
|
|
5
5
|
type parameter =
|
6
|
+
| Null
|
6
7
|
| String of string
|
7
8
|
| Float of float
|
8
9
|
| Int of int
|
9
10
|
| Bool of bool
|
10
11
|
| StringList of (string list)
|
12
|
+
| IntList of (int list)
|
11
13
|
| IntStringMap of ((string * int) list) [@@deriving eq, show]
|
12
14
|
|
13
15
|
type 'a elements = (string * 'a) list [@@deriving eq, show]
|
@@ -28,10 +30,12 @@ let surround (ch: char) (s: string): string =
|
|
28
30
|
Char.to_string ch ^ s ^ Char.to_string ch
|
29
31
|
|
30
32
|
let parameter_to_string = function
|
33
|
+
| Null -> "null"
|
31
34
|
| String s -> String.escaped s
|
32
35
|
| Float f -> Float.to_string f
|
33
36
|
| Int n -> Int.to_string n
|
34
37
|
| Bool b -> Bool.to_string b
|
35
38
|
| StringList xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:(surround '\"' >> String.escaped) xs) ^ "]"
|
39
|
+
| IntList xs -> "[" ^ String.concat ~sep:"; " (List.map ~f:Int.to_string xs) ^ "]"
|
36
40
|
| IntStringMap xs -> "[" ^ String.concat ~sep:"; "
|
37
41
|
(List.map xs ~f:(fun (k,v) -> "(\"" ^ String.escaped k ^ "\", " ^ Int.to_string v ^ ")")) ^ "]"
|
@@ -12,12 +12,19 @@ let to_int_unsafe = function
|
|
12
12
|
| `Int x -> x
|
13
13
|
| _ -> failwith "need an int here"
|
14
14
|
|
15
|
+
let to_list_safe xs = match xs with
|
16
|
+
| [] -> Some (StringList [])
|
17
|
+
| `String x :: _ -> Some (StringList (List.map xs ~f:to_string))
|
18
|
+
| `Int x :: _ -> Some (IntList (List.map xs ~f:to_int_unsafe))
|
19
|
+
| _ -> None
|
20
|
+
|
15
21
|
let to_parameter (s: json) = match s with
|
22
|
+
| `Null -> Some (Null)
|
16
23
|
| `String x -> Some (String x)
|
17
24
|
| `Float x -> Some (Float x)
|
18
25
|
| `Int x -> Some (Int x)
|
19
26
|
| `Bool x -> Some (Bool x)
|
20
|
-
| `List x ->
|
27
|
+
| `List x -> to_list_safe x
|
21
28
|
| `Assoc x -> Some (IntStringMap (List.map x ~f:(fun (k,v) -> (k,to_int_unsafe v))))
|
22
29
|
| _ -> None
|
23
30
|
|
@@ -7,6 +7,10 @@ let optional_int ~(none: int) = function
|
|
7
7
|
| Int n -> "(Some " ^ Int.to_string n ^ ")"
|
8
8
|
| x -> parameter_to_string x
|
9
9
|
|
10
|
+
let optional_int_list = function
|
11
|
+
| IntList xs -> "(Some " ^ String.concat ~sep:"; " (List.map ~f:Int.to_string xs) ^ ")"
|
12
|
+
| _ -> "None"
|
13
|
+
|
10
14
|
let optional_int_or_string ~(none: int) = function
|
11
15
|
| String s -> "(Some \"" ^ s ^ "\")"
|
12
16
|
| Int n when n = none -> "None"
|
@@ -27,6 +31,7 @@ let optional_strings ~(f: string -> bool) (parameters: (string * string) list):
|
|
27
31
|
|
28
32
|
let edit_expected ~(stringify: parameter -> string) ~(slug: string) ~(value: parameter) = match slug with
|
29
33
|
| "hamming" -> optional_int ~none:(-1) value
|
34
|
+
| "all-your-base" -> optional_int_list value
|
30
35
|
| "say" -> optional_int_or_string ~none:(-1) value
|
31
36
|
| _ -> stringify value
|
32
37
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
open Core.Std
|
2
|
+
open OUnit2
|
3
|
+
open All_your_bases
|
4
|
+
|
5
|
+
let ae exp got _test_ctxt =
|
6
|
+
assert_equal exp got ~printer:Bool.to_string
|
7
|
+
|
8
|
+
let tests = [
|
9
|
+
(* TEST
|
10
|
+
"$description" >::
|
11
|
+
ae $expected (convert_bases $input_base $input_digits $output_base);
|
12
|
+
END TEST *)
|
13
|
+
]
|
14
|
+
|
15
|
+
let () =
|
16
|
+
run_test_tt_main ("all-your-bases tests" >::: tests)
|
@@ -20,6 +20,8 @@ let model_tests = [
|
|
20
20
|
ae "[\"a\"; \"bc\"; \"def\"]" @@ parameter_to_string (StringList ["a"; "bc"; "def"]);
|
21
21
|
"string list parameter with escaped characters to string" >::
|
22
22
|
ae "[\"a\\r\"; \"b\\nc\"; \"d\\tef\"]" @@ parameter_to_string (StringList ["a\r"; "b\nc"; "d\tef"]);
|
23
|
+
"int list parameter to string" >::
|
24
|
+
ae "[1; 2; 3; 4]" @@ parameter_to_string (IntList [1; 2; 3; 4]);
|
23
25
|
"int string map parameter to string" >::
|
24
26
|
ae "[(\"one\", 1); (\"two\", 1)]" @@ parameter_to_string (IntStringMap [("one", 1); ("two", 1)]);
|
25
27
|
"int string map parameter to string with escaped characters in the keys" >::
|
@@ -40,6 +40,14 @@ let parser_tests = [
|
|
40
40
|
ae (single [{description = "d1"; parameters = []; expected = Bool true}])
|
41
41
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : true}]}");
|
42
42
|
|
43
|
+
"parses a single element with a description and expected int list output" >::
|
44
|
+
ae (single [{description = "d1"; parameters = []; expected = IntList [1;2;3]}])
|
45
|
+
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : [1, 2, 3]}]}");
|
46
|
+
|
47
|
+
"parses a single element with a description and expected null output" >::
|
48
|
+
ae (single [{description = "d1"; parameters = []; expected = Null}])
|
49
|
+
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"expected\" : null}]}");
|
50
|
+
|
43
51
|
"parses a single element with an int key value pair" >::
|
44
52
|
ae (single [{description = "d1"; parameters = [("input", Int 1996)]; expected = Bool true}])
|
45
53
|
(parse_json_text "{\"cases\" : [{\"description\" : \"d1\", \"input\" : 1996, \"expected\" : true}]}");
|
@@ -0,0 +1,57 @@
|
|
1
|
+
## Code Style and Linting
|
2
|
+
|
3
|
+
If you are looking for good general advices regarding Perl coding,
|
4
|
+
Damian Conway's [Perl Best Practices][PBP] is a good reference.
|
5
|
+
|
6
|
+
To prettify your code, you can use the module
|
7
|
+
[Perl-Tidy][PerlTidy].
|
8
|
+
|
9
|
+
To install with [cpanminus][]:
|
10
|
+
|
11
|
+
cpanm Perl-Tidy
|
12
|
+
|
13
|
+
or via the regular `cpan` install utility:
|
14
|
+
|
15
|
+
cpan Perl-Tidy
|
16
|
+
|
17
|
+
And then, you can use the provided `perltidy` utility program
|
18
|
+
to reformat your code.
|
19
|
+
|
20
|
+
# modify file in-place and save old version as some_script.pl.bak
|
21
|
+
$ perltidy -b some_script.pl
|
22
|
+
|
23
|
+
`perltidy` has a *lot* of configuration options to cater to every taste. They
|
24
|
+
are documented [here][perltidyDocs].
|
25
|
+
|
26
|
+
There is also [tidyview], a visual interface that allows you to
|
27
|
+
tweak the different options and immediately see the result.
|
28
|
+
|
29
|
+
If you want to enforce coding practices, there is also
|
30
|
+
[Perl::Critic][perlcritic]. It comes with the rules described in
|
31
|
+
the book *Perl Best Practices* mentioned previously, but plenty of
|
32
|
+
plugins exist, and it can be customized to fit any in-house coding
|
33
|
+
rules.
|
34
|
+
|
35
|
+
To install:
|
36
|
+
|
37
|
+
# via cpanminus
|
38
|
+
cpanm Perl-Critic
|
39
|
+
|
40
|
+
# via the classic 'cpan' installation tool
|
41
|
+
cpan Perl-Critic
|
42
|
+
|
43
|
+
To use:
|
44
|
+
|
45
|
+
$ perlcritic some_script.pl
|
46
|
+
|
47
|
+
The tool has many, many configuration tweaks, see its
|
48
|
+
[documentation][perlcriticdocs] for the full scoop on them.
|
49
|
+
|
50
|
+
|
51
|
+
[PBP]: http://shop.oreilly.com/product/9780596001735.do
|
52
|
+
[PerlTidy]: https://metacpan.org/release/Perl-Tidy
|
53
|
+
[cpanminus]: http://search.cpan.org/~miyagawa/App-cpanminus-1.7042
|
54
|
+
[perltidyDocs]: https://metacpan.org/pod/distribution/Perl-Tidy/docs/stylekey.pod
|
55
|
+
[tidyview]: https://sourceforge.net/projects/tidyview/
|
56
|
+
[perlcritic]: https://metacpan.org/release/Perl-Critic
|
57
|
+
[perlcriticdocs]: https://metacpan.org/pod/distribution/Perl-Critic/bin/perlcritic
|
@@ -3,10 +3,17 @@ package Example;
|
|
3
3
|
use strict;
|
4
4
|
use warnings;
|
5
5
|
|
6
|
+
use Carp;
|
7
|
+
|
6
8
|
sub compute {
|
7
9
|
my ($strand_a, $strand_b) = @_;
|
10
|
+
|
11
|
+
croak "DNA strands must be of equal length"
|
12
|
+
unless length $strand_a == length $strand_b;
|
13
|
+
|
8
14
|
my $distance = $strand_a ^ $strand_b;
|
9
15
|
$distance =~ s/\0//g;
|
16
|
+
|
10
17
|
return (length $distance) - abs(length($strand_a) - length($strand_b));
|
11
18
|
}
|
12
19
|
|
@@ -10,19 +10,32 @@ use lib $dir;
|
|
10
10
|
|
11
11
|
my $module = $ENV{EXERCISM} ? 'Example' : 'Hamming';
|
12
12
|
|
13
|
-
plan tests =>
|
13
|
+
plan tests => 12;
|
14
14
|
|
15
15
|
ok -e "${dir}${module}.pm", "Missing $module.pm" or BAIL_OUT "You need to create file: $module.pm";
|
16
16
|
eval "use $module";
|
17
17
|
ok !$@, "Cannot load $module" or BAIL_OUT "Cannot load $module. Does it compile? Does it end with 1;?";
|
18
18
|
can_ok $module, 'compute' or BAIL_OUT "Missing package $module; or missing sub compute()?";
|
19
19
|
|
20
|
+
sub dies_like(&$$) {
|
21
|
+
my( $code, $expected, $message ) = @_;
|
22
|
+
eval { $code->() };
|
23
|
+
like $@ => $expected, $message;
|
24
|
+
}
|
25
|
+
|
20
26
|
my $sub = \&{"$module" . "::compute"};
|
21
27
|
is $sub->('A', 'A'), 0, "identical strands";
|
28
|
+
is $sub->('A', 'G'), 1, "different strands";
|
22
29
|
is $sub->('AG', 'CT'), 2, "completely different strands";
|
23
30
|
is $sub->('AT', 'CT'), 1, "one hamming distance";
|
24
31
|
is $sub->('GGACG', 'GGTCG'), 1, "one hamming distance, longer strands";
|
25
|
-
is $sub->('AAAG', 'AAA'), 0, "ignore extra length on 1st strand";
|
26
|
-
is $sub->('AAA', 'AAAG'), 0, "ignore extra length on 2nd strand";
|
27
32
|
is $sub->('GATACA', 'GCATAA'), 4, "4 hamming distance";
|
28
|
-
is $sub->('GGACGGATTCTG', 'AGGACGGATTCT'), 9, "9 hamming distance"
|
33
|
+
is $sub->('GGACGGATTCTG', 'AGGACGGATTCT'), 9, "9 hamming distance";
|
34
|
+
|
35
|
+
dies_like { $sub->('AAAG', 'AAA') }
|
36
|
+
qr/DNA strands must be of equal length/,
|
37
|
+
"extra length on 1st strand";
|
38
|
+
|
39
|
+
dies_like { $sub->('AAA', 'AAAG') }
|
40
|
+
qr/DNA strands must be of equal length/,
|
41
|
+
"extra length on 2nd strand";
|
@@ -11,10 +11,10 @@ use lib $dir;
|
|
11
11
|
my $module = $ENV{EXERCISM} ? 'Example' : 'DNA';
|
12
12
|
|
13
13
|
my @cases = (
|
14
|
-
['C', 'G', '
|
15
|
-
['G', 'C', '
|
16
|
-
['T', 'A', '
|
17
|
-
['A', 'U', '
|
14
|
+
['C', 'G', 'cytosine unchanged'],
|
15
|
+
['G', 'C', 'guanine unchanged'],
|
16
|
+
['T', 'A', 'adenine unchanged'],
|
17
|
+
['A', 'U', 'thymine to uracil'],
|
18
18
|
['ACGTGGTCTTAA', 'UGCACCAGAAUU', 'transcribes all occurences'],
|
19
19
|
);
|
20
20
|
|
data/tracks/perl6/.gitignore
CHANGED
data/tracks/perl6/config.json
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
use v6;
|
2
|
+
|
3
|
+
class X::Phone::Invalid is Exception {
|
4
|
+
has $.payload;
|
5
|
+
method message {"'$!payload' is not valid."}
|
6
|
+
}
|
7
|
+
|
8
|
+
class Phone {
|
9
|
+
has $.number;
|
10
|
+
|
11
|
+
method new (:$number!) {
|
12
|
+
my $validated = $number;
|
13
|
+
$validated ~~ s:g/<:!Decimal_Number>//;
|
14
|
+
$validated ~~ /^ 1? (\d ** 10) $/ ?? ($validated = ~$0) !! X::Phone::Invalid.new(:payload«$number»).throw;
|
15
|
+
self.bless(:number«$validated»);
|
16
|
+
}
|
17
|
+
|
18
|
+
method area-code {
|
19
|
+
$!number ~~ /\d**3/ and return ~$/;
|
20
|
+
}
|
21
|
+
|
22
|
+
method pretty {
|
23
|
+
$!number ~~ /
|
24
|
+
$<area-code> = \d**3
|
25
|
+
$<central-office-code> = \d**3
|
26
|
+
$<station-number> = \d**4
|
27
|
+
/ and return "($<area-code>) $<central-office-code>-$<station-number>";
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
{
|
2
|
+
"valid": [
|
3
|
+
{
|
4
|
+
"input": 1234567890,
|
5
|
+
"number": "1234567890",
|
6
|
+
"area-code": "123",
|
7
|
+
"pretty": "(123) 456-7890",
|
8
|
+
"test": "10 digit integer"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"input": "+1 (234) 555-6789",
|
12
|
+
"number": "2345556789",
|
13
|
+
"area-code": "234",
|
14
|
+
"pretty": "(234) 555-6789",
|
15
|
+
"test": "11 digit formatted number"
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"input": "1.379.555.2468",
|
19
|
+
"number": "3795552468",
|
20
|
+
"area-code": "379",
|
21
|
+
"pretty": "(379) 555-2468",
|
22
|
+
"test": "11 digit number containing separators"
|
23
|
+
}
|
24
|
+
],
|
25
|
+
"invalid": [
|
26
|
+
{
|
27
|
+
"input": "",
|
28
|
+
"test": "empty input"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"input": "13579",
|
32
|
+
"test": "5 digit number"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"input": "123456789011",
|
36
|
+
"test": "12 digit number"
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"input": "+2 (468) 555-1379",
|
40
|
+
"test": "11 digit number not beginning with 1"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"input": "phone number",
|
44
|
+
"test": "not a number"
|
45
|
+
}
|
46
|
+
]
|
47
|
+
}
|