trackler 2.2.1.137 → 2.2.1.138
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/diffie-hellman/canonical-data.json +72 -0
- data/problem-specifications/exercises/yacht/description.md +2 -2
- data/tracks/csharp/exercises/sgf-parsing/Example.cs +1 -1
- data/tracks/csharp/exercises/sgf-parsing/SgfParsingTest.cs +1 -1
- data/tracks/csharp/exercises/sublist/SublistTest.cs +37 -78
- data/tracks/csharp/generators/Exercises/Sublist.cs +32 -0
- data/tracks/elisp/exercises/bob/README.md +2 -0
- data/tracks/elisp/exercises/bob/bob-test.el +60 -15
- data/tracks/elisp/exercises/bob/example.el +15 -5
- data/tracks/elisp/exercises/hamming/hamming-test.el +1 -1
- data/tracks/fsharp/build.ps1 +3 -3
- data/tracks/fsharp/build.sh +3 -3
- data/tracks/fsharp/exercises/bracket-push/BracketPushTest.fs +5 -1
- data/tracks/fsharp/exercises/isbn-verifier/IsbnVerifierTest.fs +5 -1
- data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGardenTest.fs +1 -1
- data/tracks/fsharp/exercises/pov/PovTest.fs +6 -1
- data/tracks/fsharp/exercises/react/Example.fs +2 -2
- data/tracks/fsharp/exercises/react/React.fsproj +1 -0
- data/tracks/fsharp/exercises/react/ReactTest.fs +55 -33
- data/tracks/fsharp/exercises/series/Example.fs +2 -12
- data/tracks/fsharp/exercises/series/SeriesTest.fs +33 -56
- data/tracks/fsharp/generators/Generators.fs +81 -46
- data/tracks/idris/exercises/rna-transcription/src/{example.idr → Example.idr} +0 -0
- data/tracks/java/config.json +14 -0
- data/tracks/java/exercises/acronym/src/test/java/AcronymTest.java +10 -10
- data/tracks/java/exercises/all-your-base/src/test/java/BaseConverterTest.java +39 -39
- data/tracks/java/exercises/grep/.meta/hints.md +58 -0
- data/tracks/java/exercises/grep/.meta/src/reference/java/GrepTool.java +65 -0
- data/tracks/java/exercises/grep/.meta/version +1 -0
- data/tracks/java/exercises/grep/README.md +145 -0
- data/tracks/java/exercises/grep/build.gradle +18 -0
- data/tracks/java/exercises/grep/src/main/java/.keep +0 -0
- data/tracks/java/exercises/grep/src/test/java/GrepToolTest.java +395 -0
- data/tracks/java/exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java +36 -36
- data/tracks/java/exercises/minesweeper/src/test/java/MinesweeperBoardTest.java +36 -36
- data/tracks/java/exercises/phone-number/src/test/java/PhoneNumberTest.java +14 -14
- data/tracks/java/exercises/poker/src/test/java/PokerTest.java +40 -40
- data/tracks/java/exercises/pythagorean-triplet/src/test/java/PythagoreanTripletTest.java +10 -10
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/ocaml/exercises/anagram/example.ml +1 -1
- data/tracks/ocaml/exercises/change/example.ml +1 -1
- data/tracks/ocaml/exercises/custom-set/example.ml +4 -3
- data/tracks/ocaml/exercises/custom-set/test.ml +0 -1
- data/tracks/ocaml/exercises/dominoes/test.ml +1 -1
- data/tracks/ocaml/exercises/etl/example.ml +1 -1
- data/tracks/ocaml/exercises/grade-school/example.ml +1 -1
- data/tracks/ocaml/exercises/palindrome-products/example.ml +2 -2
- data/tracks/ocaml/exercises/prime-factors/example.ml +1 -1
- data/tracks/ocaml/exercises/robot-name/test.ml +1 -1
- data/tracks/ocaml/exercises/triangle/example.ml +1 -1
- data/tracks/ocaml/make-exercise.sh +1 -0
- data/tracks/ocaml/tools/test-generator/src/controller.ml +1 -1
- data/tracks/perl5/exercises/raindrops/.meta/solutions/Raindrops.pm +13 -12
- data/tracks/perl5/exercises/raindrops/raindrops.t +166 -111
- data/tracks/perl6/docs/INSTALLATION.md +1 -3
- data/tracks/perl6/exercises/raindrops/.meta/exercise-data.yaml +5 -5
- data/tracks/perl6/exercises/raindrops/.meta/solutions/Raindrops.pm6 +2 -2
- data/tracks/perl6/exercises/raindrops/Raindrops.pm6 +2 -2
- data/tracks/perl6/exercises/raindrops/raindrops.t +3 -3
- data/tracks/python/exercises/food-chain/example.py +11 -2
- data/tracks/python/exercises/food-chain/food_chain_test.py +48 -45
- data/tracks/python/exercises/pov/pov_test.py +12 -1
- data/tracks/python/exercises/series/README.md +6 -6
- data/tracks/python/exercises/series/example.py +2 -3
- data/tracks/python/exercises/series/series_test.py +27 -28
- data/tracks/python/exercises/sgf-parsing/example.py +1 -1
- data/tracks/python/exercises/sgf-parsing/sgf_parsing_test.py +1 -1
- data/tracks/python/exercises/yacht/README.md +2 -2
- data/tracks/ruby/Gemfile +0 -1
- data/tracks/ruby/README.md +23 -0
- data/tracks/ruby/bin/generate +1 -0
- data/tracks/ruby/exercises/complex-numbers/complex_numbers_test.rb +1 -1
- data/tracks/ruby/lib/generator.rb +1 -2
- data/tracks/ruby/lib/generator/command_line.rb +3 -0
- data/tracks/ruby/lib/generator/command_line/generator_optparser.rb +1 -0
- data/tracks/ruby/lib/generator/exercise.rb +2 -0
- data/tracks/ruby/lib/generator/exercise_case.rb +3 -0
- data/tracks/ruby/lib/generator/files.rb +1 -0
- data/tracks/ruby/lib/generator/files/metadata_files.rb +2 -0
- data/tracks/ruby/lib/generator/files/track_files.rb +1 -0
- data/tracks/ruby/lib/generator/implementation.rb +1 -0
- data/tracks/ruby/lib/generator/repository.rb +3 -0
- data/tracks/ruby/lib/generator/template_values.rb +1 -0
- data/tracks/ruby/test/generator/case_values_test.rb +2 -0
- data/tracks/ruby/test/generator/command_line_test.rb +1 -0
- data/tracks/ruby/test/generator/files/metadata_files_test.rb +2 -0
- data/tracks/ruby/test/generator/files/track_files_test.rb +1 -0
- data/tracks/ruby/test/generator/implementation_test.rb +1 -0
- data/tracks/ruby/test/tasks/exercise_test.rb +1 -0
- data/tracks/ruby/test/tasks/exercise_test_tasks_test.rb +2 -0
- data/tracks/ruby/test/test_helper.rb +1 -3
- data/tracks/rust/config.json +12 -0
- data/tracks/rust/exercises/atbash-cipher/src/lib.rs +9 -0
- data/tracks/rust/exercises/hamming/src/lib.rs +6 -0
- data/tracks/rust/exercises/isogram/src/lib.rs +3 -0
- data/tracks/rust/exercises/luhn/src/lib.rs +4 -0
- data/tracks/rust/exercises/palindrome-products/.meta/test-in-release-mode +1 -0
- data/tracks/rust/exercises/palindrome-products/Cargo.toml +6 -0
- data/tracks/rust/exercises/palindrome-products/README.md +72 -0
- data/tracks/rust/exercises/palindrome-products/example.rs +25 -0
- data/tracks/rust/exercises/palindrome-products/src/lib.rs +22 -0
- data/tracks/rust/exercises/palindrome-products/tests/palindrome-products.rs +57 -0
- data/tracks/rust/exercises/pangram/src/lib.rs +4 -0
- data/tracks/rust/exercises/run-length-encoding/src/lib.rs +7 -0
- data/tracks/rust/exercises/say/src/lib.rs +3 -4
- data/tracks/rust/exercises/scrabble-score/src/lib.rs +4 -0
- data/tracks/rust/exercises/word-count/src/lib.rs +6 -0
- data/tracks/scheme/exercises/hello-world/example.scm +1 -4
- data/tracks/scheme/exercises/hello-world/hello-world-test.scm +1 -5
- data/tracks/scheme/exercises/scrabble-score/scrabble-score-test.scm +2 -2
- data/tracks/typescript/config.json +30 -0
- data/tracks/typescript/exercises/queen-attack/README.md +59 -0
- data/tracks/typescript/exercises/queen-attack/package.json +36 -0
- data/tracks/typescript/exercises/queen-attack/queen-attack.example.ts +56 -0
- data/tracks/typescript/exercises/queen-attack/queen-attack.test.ts +71 -0
- data/tracks/typescript/exercises/queen-attack/queen-attack.ts +0 -0
- data/tracks/typescript/exercises/queen-attack/tsconfig.json +22 -0
- data/tracks/typescript/exercises/queen-attack/tslint.json +127 -0
- data/tracks/typescript/exercises/queen-attack/yarn.lock +2624 -0
- data/tracks/typescript/exercises/spiral-matrix/README.md +56 -0
- data/tracks/typescript/exercises/spiral-matrix/package.json +36 -0
- data/tracks/typescript/exercises/spiral-matrix/spiral-matrix.example.ts +33 -0
- data/tracks/typescript/exercises/spiral-matrix/spiral-matrix.test.ts +49 -0
- data/tracks/typescript/exercises/spiral-matrix/spiral-matrix.ts +0 -0
- data/tracks/typescript/exercises/spiral-matrix/tsconfig.json +22 -0
- data/tracks/typescript/exercises/spiral-matrix/tslint.json +127 -0
- data/tracks/typescript/exercises/spiral-matrix/yarn.lock +2624 -0
- metadata +35 -3
@@ -5,10 +5,12 @@
|
|
5
5
|
;;; Code:
|
6
6
|
(defun response-for (phrase)
|
7
7
|
"Provides Bob's response to PHRASE."
|
8
|
-
(
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
(let ((stripped-phrase (chomp phrase)))
|
9
|
+
(cond ((shout-questionp stripped-phrase) "Calm down, I know what I'm doing!")
|
10
|
+
((shoutp stripped-phrase) "Whoa, chill out!")
|
11
|
+
((string-match-p "^[[:space:]]*$" stripped-phrase) "Fine. Be that way!")
|
12
|
+
((questionp stripped-phrase) "Sure.")
|
13
|
+
(t "Whatever."))))
|
12
14
|
|
13
15
|
(defun shoutp (phrase)
|
14
16
|
"Determines if PHRASE is shouted."
|
@@ -20,8 +22,16 @@
|
|
20
22
|
(and (> (length phrase) 0)
|
21
23
|
(= ?? (aref phrase (1- (length phrase))))))
|
22
24
|
|
25
|
+
(defun shout-questionp (phrase)
|
26
|
+
"Determines if PHRASE is a shouted question."
|
27
|
+
(and (shoutp phrase) (questionp phrase)))
|
23
28
|
|
24
|
-
|
29
|
+
(defun chomp (str)
|
30
|
+
"Chomp leading and tailing whitespace from STR."
|
31
|
+
(replace-regexp-in-string (rx (or (: bos (* (any " \t\n")))
|
32
|
+
(: (* (any " \t\n")) eos)))
|
33
|
+
""
|
34
|
+
str))
|
25
35
|
|
26
36
|
(provide 'bob)
|
27
37
|
;;; bob.el ends here
|
@@ -48,7 +48,7 @@
|
|
48
48
|
(ert-deftest disallow-first-strand-longer ()
|
49
49
|
(should-error (hamming-distance "AATG" "AAA")))
|
50
50
|
|
51
|
-
(ert-deftest disallow-
|
51
|
+
(ert-deftest disallow-second-strand-longer ()
|
52
52
|
(should-error (hamming-distance "ATA" "AGTG")))
|
53
53
|
|
54
54
|
(provide 'hamming-test)
|
data/tracks/fsharp/build.ps1
CHANGED
@@ -25,12 +25,12 @@ Param(
|
|
25
25
|
|
26
26
|
$SCRIPT_DIR = $PSScriptRoot
|
27
27
|
$TOOLS_DIR = Join-Path $SCRIPT_DIR "tools"
|
28
|
-
$CAKE_VERSION = "0.
|
28
|
+
$CAKE_VERSION = "0.27.1"
|
29
29
|
$CAKE_DIR = Join-Path $TOOLS_DIR "Cake.$CAKE_VERSION"
|
30
30
|
$CAKE_DLL = Join-Path $CAKE_DIR "Cake.dll"
|
31
31
|
$CAKE_ZIP = Join-Path $TOOLS_DIR "Cake.$CAKE_VERSION.zip"
|
32
|
-
$CAKE_ZIP_URL = "https://github.com/cake-build/cake/releases/download/
|
33
|
-
$DOTNET_VERSION = "2.
|
32
|
+
$CAKE_ZIP_URL = "https://github.com/cake-build/cake/releases/download/v$CAKE_VERSION/Cake-bin-coreclr-v$CAKE_VERSION.zip"
|
33
|
+
$DOTNET_VERSION = "2.1.105"
|
34
34
|
$DOTNET_DIR = Join-Path $TOOLS_DIR "dotnet.$DOTNET_VERSION"
|
35
35
|
$DOTNET_COMMAND = Join-Path $DOTNET_DIR "dotnet.exe"
|
36
36
|
$DOTNET_INSTALL_SCRIPT = Join-Path $DOTNET_DIR "dotnet-install.ps1"
|
data/tracks/fsharp/build.sh
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
4
4
|
TOOLS_DIR=$SCRIPT_DIR/tools
|
5
|
-
CAKE_VERSION=0.
|
5
|
+
CAKE_VERSION=0.27.1
|
6
6
|
CAKE_DIR=$TOOLS_DIR/Cake.$CAKE_VERSION
|
7
7
|
CAKE_DLL=$CAKE_DIR/Cake.dll
|
8
8
|
CAKE_ZIP=$TOOLS_DIR/Cake.$CAKE_VERSION.zip
|
9
|
-
CAKE_ZIP_URL=https://github.com/cake-build/cake/releases/download/
|
10
|
-
DOTNET_VERSION=2.
|
9
|
+
CAKE_ZIP_URL=https://github.com/cake-build/cake/releases/download/v$CAKE_VERSION/Cake-bin-coreclr-v$CAKE_VERSION.zip
|
10
|
+
DOTNET_VERSION=2.1.105
|
11
11
|
DOTNET_DIR=$TOOLS_DIR/dotnet.$DOTNET_VERSION
|
12
12
|
DOTNET_COMMAND=$DOTNET_DIR/dotnet
|
13
13
|
DOTNET_INSTALL_SCRIPT=$DOTNET_DIR/dotnet-install.sh
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// This file was auto-generated based on version 1.
|
1
|
+
// This file was auto-generated based on version 1.3.0 of the canonical data.
|
2
2
|
|
3
3
|
module BracketPushTest
|
4
4
|
|
@@ -31,6 +31,10 @@ let ``Wrong closing bracket`` () =
|
|
31
31
|
let ``Paired with whitespace`` () =
|
32
32
|
isPaired "{ }" |> should equal true
|
33
33
|
|
34
|
+
[<Fact(Skip = "Remove to run test")>]
|
35
|
+
let ``Partially paired brackets`` () =
|
36
|
+
isPaired "{[])" |> should equal false
|
37
|
+
|
34
38
|
[<Fact(Skip = "Remove to run test")>]
|
35
39
|
let ``Simple nested brackets`` () =
|
36
40
|
isPaired "{[]}" |> should equal true
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// This file was auto-generated based on version 2.
|
1
|
+
// This file was auto-generated based on version 2.4.0 of the canonical data.
|
2
2
|
|
3
3
|
module IsbnVerifierTest
|
4
4
|
|
@@ -63,3 +63,7 @@ let ``Check digit of X should not be used for 0`` () =
|
|
63
63
|
let ``Empty isbn`` () =
|
64
64
|
isValid "" |> should equal false
|
65
65
|
|
66
|
+
[<Fact(Skip = "Remove to run test")>]
|
67
|
+
let ``Input is 9 characters`` () =
|
68
|
+
isValid "134456729" |> should equal false
|
69
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// This file was auto-generated based on version 1.
|
1
|
+
// This file was auto-generated based on version 1.3.0 of the canonical data.
|
2
2
|
|
3
3
|
module PovTest
|
4
4
|
|
@@ -76,6 +76,11 @@ let ``Can find path to cousin`` () =
|
|
76
76
|
let tree = mkGraph "grandparent" [mkGraph "parent" [mkGraph "x" [mkGraph "kid-0" []; mkGraph "kid-1" []]; mkGraph "sibling-0" []; mkGraph "sibling-1" []]; mkGraph "uncle" [mkGraph "cousin-0" []; mkGraph "cousin-1" []]]
|
77
77
|
tracePathBetween "x" "cousin-1" tree |> should equal <| Some ["x"; "parent"; "grandparent"; "uncle"; "cousin-1"]
|
78
78
|
|
79
|
+
[<Fact(Skip = "Remove to run test")>]
|
80
|
+
let ``Can find path not involving root`` () =
|
81
|
+
let tree = mkGraph "grandparent" [mkGraph "parent" [mkGraph "x" []; mkGraph "sibling-0" []; mkGraph "sibling-1" []]]
|
82
|
+
tracePathBetween "x" "sibling-1" tree |> should equal <| Some ["x"; "parent"; "sibling-1"]
|
83
|
+
|
79
84
|
[<Fact(Skip = "Remove to run test")>]
|
80
85
|
let ``Can find path from nodes other than x`` () =
|
81
86
|
let tree = mkGraph "parent" [mkGraph "a" []; mkGraph "x" []; mkGraph "b" []; mkGraph "c" []]
|
@@ -55,10 +55,10 @@ type Reactor() =
|
|
55
55
|
cells <- cells @ [cell]
|
56
56
|
cell
|
57
57
|
|
58
|
-
member
|
58
|
+
member __.createInputCell value =
|
59
59
|
addCell value
|
60
60
|
|
61
|
-
member
|
61
|
+
member __.createComputeCell (producers: Cell list) (compute: (int list -> int)) =
|
62
62
|
let value = computeValue producers compute
|
63
63
|
let cell = addCell value
|
64
64
|
cell.Producers <- producers
|
@@ -17,6 +17,7 @@
|
|
17
17
|
<PackageReference Include="xunit" Version="2.3.1" />
|
18
18
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
19
19
|
<PackageReference Include="FsUnit.xUnit" Version="3.1.0" />
|
20
|
+
<PackageReference Include="FakeItEasy" Version="4.5.1" />
|
20
21
|
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
21
22
|
</ItemGroup>
|
22
23
|
|
@@ -1,9 +1,10 @@
|
|
1
|
-
// This file was auto-generated based on version
|
1
|
+
// This file was auto-generated based on version 2.0.0 of the canonical data.
|
2
2
|
|
3
3
|
module ReactTest
|
4
4
|
|
5
5
|
open FsUnit.Xunit
|
6
6
|
open Xunit
|
7
|
+
open FakeItEasy
|
7
8
|
|
8
9
|
open React
|
9
10
|
|
@@ -59,76 +60,95 @@ let ``Compute cells fire callbacks`` () =
|
|
59
60
|
let reactor = new Reactor()
|
60
61
|
let input = reactor.createInputCell 1
|
61
62
|
let output = reactor.createComputeCell [input] (fun values -> values.[0] + 1)
|
62
|
-
let
|
63
|
-
let callback1Handler = Handler<int>(fun _ value -> callback1 <- callback1 @ [value])
|
63
|
+
let callback1Handler = A.Fake<Handler<int>>()
|
64
64
|
output.Changed.AddHandler callback1Handler
|
65
65
|
input.Value <- 3
|
66
|
-
|
66
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, 4)).MustHaveHappenedOnceExactly() |> ignore
|
67
|
+
Fake.ClearRecordedCalls(callback1Handler) |> ignore
|
67
68
|
|
68
69
|
[<Fact(Skip = "Remove to run test")>]
|
69
70
|
let ``Callback cells only fire on change`` () =
|
70
71
|
let reactor = new Reactor()
|
71
72
|
let input = reactor.createInputCell 1
|
72
73
|
let output = reactor.createComputeCell [input] (fun values -> if values.[0] < 3 then 111 else 222)
|
73
|
-
let
|
74
|
-
let callback1Handler = Handler<int>(fun _ value -> callback1 <- callback1 @ [value])
|
74
|
+
let callback1Handler = A.Fake<Handler<int>>()
|
75
75
|
output.Changed.AddHandler callback1Handler
|
76
76
|
input.Value <- 2
|
77
|
-
|
77
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, A<int>.``_``)).MustNotHaveHappened() |> ignore
|
78
78
|
input.Value <- 4
|
79
|
-
|
79
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, 222)).MustHaveHappenedOnceExactly() |> ignore
|
80
|
+
Fake.ClearRecordedCalls(callback1Handler) |> ignore
|
80
81
|
|
81
82
|
[<Fact(Skip = "Remove to run test")>]
|
82
83
|
let ``Callbacks do not report already reported values`` () =
|
83
84
|
let reactor = new Reactor()
|
84
85
|
let input = reactor.createInputCell 1
|
85
86
|
let output = reactor.createComputeCell [input] (fun values -> values.[0] + 1)
|
86
|
-
let
|
87
|
-
let callback1Handler = Handler<int>(fun _ value -> callback1 <- [value])
|
87
|
+
let callback1Handler = A.Fake<Handler<int>>()
|
88
88
|
output.Changed.AddHandler callback1Handler
|
89
89
|
input.Value <- 2
|
90
|
-
|
90
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, 3)).MustHaveHappenedOnceExactly() |> ignore
|
91
|
+
Fake.ClearRecordedCalls(callback1Handler) |> ignore
|
91
92
|
input.Value <- 3
|
92
|
-
|
93
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, 4)).MustHaveHappenedOnceExactly() |> ignore
|
94
|
+
Fake.ClearRecordedCalls(callback1Handler) |> ignore
|
95
|
+
|
96
|
+
[<Fact(Skip = "Remove to run test")>]
|
97
|
+
let ``Callbacks can fire from multiple cells`` () =
|
98
|
+
let reactor = new Reactor()
|
99
|
+
let input = reactor.createInputCell 1
|
100
|
+
let plus_one = reactor.createComputeCell [input] (fun values -> values.[0] + 1)
|
101
|
+
let minus_one = reactor.createComputeCell [input] (fun values -> values.[0] - 1)
|
102
|
+
let callback1Handler = A.Fake<Handler<int>>()
|
103
|
+
plus_one.Changed.AddHandler callback1Handler
|
104
|
+
let callback2Handler = A.Fake<Handler<int>>()
|
105
|
+
minus_one.Changed.AddHandler callback2Handler
|
106
|
+
input.Value <- 10
|
107
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, 11)).MustHaveHappenedOnceExactly() |> ignore
|
108
|
+
Fake.ClearRecordedCalls(callback1Handler) |> ignore
|
109
|
+
A.CallTo(fun() -> callback2Handler.Invoke(A<obj>.``_``, 9)).MustHaveHappenedOnceExactly() |> ignore
|
110
|
+
Fake.ClearRecordedCalls(callback2Handler) |> ignore
|
93
111
|
|
94
112
|
[<Fact(Skip = "Remove to run test")>]
|
95
113
|
let ``Callbacks can be added and removed`` () =
|
96
114
|
let reactor = new Reactor()
|
97
115
|
let input = reactor.createInputCell 11
|
98
116
|
let output = reactor.createComputeCell [input] (fun values -> values.[0] + 1)
|
99
|
-
let
|
100
|
-
let callback1Handler = Handler<int>(fun _ value -> callback1 <- callback1 @ [value])
|
117
|
+
let callback1Handler = A.Fake<Handler<int>>()
|
101
118
|
output.Changed.AddHandler callback1Handler
|
102
|
-
let
|
103
|
-
let callback2Handler = Handler<int>(fun _ value -> callback2 <- callback2 @ [value])
|
119
|
+
let callback2Handler = A.Fake<Handler<int>>()
|
104
120
|
output.Changed.AddHandler callback2Handler
|
105
121
|
input.Value <- 31
|
122
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, 32)).MustHaveHappenedOnceExactly() |> ignore
|
123
|
+
Fake.ClearRecordedCalls(callback1Handler) |> ignore
|
124
|
+
A.CallTo(fun() -> callback2Handler.Invoke(A<obj>.``_``, 32)).MustHaveHappenedOnceExactly() |> ignore
|
125
|
+
Fake.ClearRecordedCalls(callback2Handler) |> ignore
|
106
126
|
output.Changed.RemoveHandler callback1Handler
|
107
|
-
let
|
108
|
-
let callback3Handler = Handler<int>(fun _ value -> callback3 <- callback3 @ [value])
|
127
|
+
let callback3Handler = A.Fake<Handler<int>>()
|
109
128
|
output.Changed.AddHandler callback3Handler
|
110
129
|
input.Value <- 41
|
111
|
-
|
112
|
-
|
113
|
-
|
130
|
+
A.CallTo(fun() -> callback2Handler.Invoke(A<obj>.``_``, 42)).MustHaveHappenedOnceExactly() |> ignore
|
131
|
+
Fake.ClearRecordedCalls(callback2Handler) |> ignore
|
132
|
+
A.CallTo(fun() -> callback3Handler.Invoke(A<obj>.``_``, 42)).MustHaveHappenedOnceExactly() |> ignore
|
133
|
+
Fake.ClearRecordedCalls(callback3Handler) |> ignore
|
134
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, A<int>.``_``)).MustNotHaveHappened() |> ignore
|
114
135
|
|
115
136
|
[<Fact(Skip = "Remove to run test")>]
|
116
137
|
let ``Removing a callback multiple times doesn't interfere with other callbacks`` () =
|
117
138
|
let reactor = new Reactor()
|
118
139
|
let input = reactor.createInputCell 1
|
119
140
|
let output = reactor.createComputeCell [input] (fun values -> values.[0] + 1)
|
120
|
-
let
|
121
|
-
let callback1Handler = Handler<int>(fun _ value -> callback1 <- callback1 @ [value])
|
141
|
+
let callback1Handler = A.Fake<Handler<int>>()
|
122
142
|
output.Changed.AddHandler callback1Handler
|
123
|
-
let
|
124
|
-
let callback2Handler = Handler<int>(fun _ value -> callback2 <- callback2 @ [value])
|
143
|
+
let callback2Handler = A.Fake<Handler<int>>()
|
125
144
|
output.Changed.AddHandler callback2Handler
|
126
145
|
output.Changed.RemoveHandler callback1Handler
|
127
146
|
output.Changed.RemoveHandler callback1Handler
|
128
147
|
output.Changed.RemoveHandler callback1Handler
|
129
148
|
input.Value <- 2
|
130
|
-
|
131
|
-
|
149
|
+
A.CallTo(fun() -> callback2Handler.Invoke(A<obj>.``_``, 3)).MustHaveHappenedOnceExactly() |> ignore
|
150
|
+
Fake.ClearRecordedCalls(callback2Handler) |> ignore
|
151
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, A<int>.``_``)).MustNotHaveHappened() |> ignore
|
132
152
|
|
133
153
|
[<Fact(Skip = "Remove to run test")>]
|
134
154
|
let ``Callbacks should only be called once even if multiple dependencies change`` () =
|
@@ -138,11 +158,11 @@ let ``Callbacks should only be called once even if multiple dependencies change`
|
|
138
158
|
let minus_one1 = reactor.createComputeCell [input] (fun values -> values.[0] - 1)
|
139
159
|
let minus_one2 = reactor.createComputeCell [minus_one1] (fun values -> values.[0] - 1)
|
140
160
|
let output = reactor.createComputeCell [plus_one; minus_one2] (fun values -> values.[0] * values.[1])
|
141
|
-
let
|
142
|
-
let callback1Handler = Handler<int>(fun _ value -> callback1 <- callback1 @ [value])
|
161
|
+
let callback1Handler = A.Fake<Handler<int>>()
|
143
162
|
output.Changed.AddHandler callback1Handler
|
144
163
|
input.Value <- 4
|
145
|
-
|
164
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, 10)).MustHaveHappenedOnceExactly() |> ignore
|
165
|
+
Fake.ClearRecordedCalls(callback1Handler) |> ignore
|
146
166
|
|
147
167
|
[<Fact(Skip = "Remove to run test")>]
|
148
168
|
let ``Callbacks should not be called if dependencies change but output value doesn't change`` () =
|
@@ -151,12 +171,14 @@ let ``Callbacks should not be called if dependencies change but output value doe
|
|
151
171
|
let plus_one = reactor.createComputeCell [input] (fun values -> values.[0] + 1)
|
152
172
|
let minus_one = reactor.createComputeCell [input] (fun values -> values.[0] - 1)
|
153
173
|
let always_two = reactor.createComputeCell [plus_one; minus_one] (fun values -> values.[0] - values.[1])
|
154
|
-
let
|
155
|
-
let callback1Handler = Handler<int>(fun _ value -> callback1 <- callback1 @ [value])
|
174
|
+
let callback1Handler = A.Fake<Handler<int>>()
|
156
175
|
always_two.Changed.AddHandler callback1Handler
|
157
176
|
input.Value <- 2
|
177
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, A<int>.``_``)).MustNotHaveHappened() |> ignore
|
158
178
|
input.Value <- 3
|
179
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, A<int>.``_``)).MustNotHaveHappened() |> ignore
|
159
180
|
input.Value <- 4
|
181
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, A<int>.``_``)).MustNotHaveHappened() |> ignore
|
160
182
|
input.Value <- 5
|
161
|
-
|
183
|
+
A.CallTo(fun() -> callback1Handler.Invoke(A<obj>.``_``, A<int>.``_``)).MustNotHaveHappened() |> ignore
|
162
184
|
|
@@ -1,15 +1,5 @@
|
|
1
1
|
module Series
|
2
2
|
|
3
|
-
open System
|
4
|
-
|
5
|
-
let charToDigit c = c.ToString() |> Int32.Parse
|
6
|
-
let digits str = str |> List.ofSeq |> List.map charToDigit
|
7
|
-
let slice length input = Seq.take length input |> List.ofSeq
|
8
|
-
|
9
|
-
let rec slicesHelper length remainder acc =
|
10
|
-
if remainder |> List.length < length then acc |> List.rev
|
11
|
-
else slicesHelper length (remainder |> List.tail) (slice length remainder:: acc)
|
12
|
-
|
13
3
|
let slices (str:string) length =
|
14
|
-
if length
|
15
|
-
else
|
4
|
+
if length < 1 || length > str.Length || str.Length = 0 then None
|
5
|
+
else Some [for i in 0 .. str.Length - length -> str.[i..i + length - 1]]
|
@@ -1,72 +1,49 @@
|
|
1
|
-
// This file was
|
1
|
+
// This file was auto-generated based on version 1.0.0 of the canonical data.
|
2
2
|
|
3
3
|
module SeriesTest
|
4
4
|
|
5
|
-
open System
|
6
|
-
open Xunit
|
7
5
|
open FsUnit.Xunit
|
6
|
+
open Xunit
|
7
|
+
|
8
8
|
open Series
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
theoryData.Add("01234", [[0]; [1]; [2]; [3]; [4]])
|
14
|
-
theoryData.Add("92834", [[9]; [2]; [8]; [3]; [4]])
|
15
|
-
theoryData
|
10
|
+
[<Fact>]
|
11
|
+
let ``Slices of one from one`` () =
|
12
|
+
slices "1" 1 |> should equal (Some ["1"])
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
slices input 1 |> should equal expected
|
14
|
+
[<Fact(Skip = "Remove to run test")>]
|
15
|
+
let ``Slices of one from two`` () =
|
16
|
+
slices "12" 1 |> should equal (Some ["1"; "2"])
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
theoryData.Add("98273463", [[9; 8]; [8; 2]; [2; 7]; [7; 3]; [3; 4]; [4; 6]; [6; 3]]);
|
26
|
-
theoryData.Add("37103", [[3; 7]; [7; 1]; [1; 0]; [0; 3]])
|
27
|
-
theoryData
|
18
|
+
[<Fact(Skip = "Remove to run test")>]
|
19
|
+
let ``Slices of two`` () =
|
20
|
+
slices "35" 2 |> should equal (Some ["35"])
|
28
21
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
slices input 2 |> should equal expected
|
22
|
+
[<Fact(Skip = "Remove to run test")>]
|
23
|
+
let ``Slices of two overlap`` () =
|
24
|
+
slices "9142" 2 |> should equal (Some ["91"; "14"; "42"])
|
33
25
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
theoryData.Add("31001", [[3; 1; 0]; [1; 0; 0]; [0; 0; 1]]);
|
38
|
-
theoryData.Add("982347", [[9; 8; 2]; [8; 2; 3]; [2; 3; 4]; [3; 4; 7]])
|
39
|
-
theoryData
|
26
|
+
[<Fact(Skip = "Remove to run test")>]
|
27
|
+
let ``Slices can include duplicates`` () =
|
28
|
+
slices "777777" 3 |> should equal (Some ["777"; "777"; "777"; "777"])
|
40
29
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
slices input 3 |> should equal expected
|
30
|
+
[<Fact(Skip = "Remove to run test")>]
|
31
|
+
let ``Slices of a long series`` () =
|
32
|
+
slices "918493904243" 5 |> should equal (Some ["91849"; "18493"; "84939"; "49390"; "93904"; "39042"; "90424"; "04243"])
|
45
33
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
theoryData.Add("91274", [[9; 1; 2; 7]; [1; 2; 7; 4]])
|
50
|
-
theoryData
|
34
|
+
[<Fact(Skip = "Remove to run test")>]
|
35
|
+
let ``Slice length is too large`` () =
|
36
|
+
slices "12345" 6 |> should equal None
|
51
37
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
slices input 4 |> should equal expected
|
38
|
+
[<Fact(Skip = "Remove to run test")>]
|
39
|
+
let ``Slice length cannot be zero`` () =
|
40
|
+
slices "12345" 0 |> should equal None
|
56
41
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
theoryData.Add("81228", [[8; 1; 2; 2; 8]])
|
61
|
-
theoryData
|
42
|
+
[<Fact(Skip = "Remove to run test")>]
|
43
|
+
let ``Slice length cannot be negative`` () =
|
44
|
+
slices "123" -1 |> should equal None
|
62
45
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
slices input 5 |> should equal expected
|
46
|
+
[<Fact(Skip = "Remove to run test")>]
|
47
|
+
let ``Empty series is invalid`` () =
|
48
|
+
slices "" 1 |> should equal None
|
67
49
|
|
68
|
-
[<Theory(Skip = "Remove to run test")>]
|
69
|
-
[<InlineData("01234", 6)>]
|
70
|
-
[<InlineData("01032987583", 19)>]
|
71
|
-
member this.``Slice longer than input is not allowed`` input slice =
|
72
|
-
(fun () -> slices input slice |> ignore) |> should throw typeof<ArgumentException>
|
@@ -1085,9 +1085,7 @@ type RationalNumbers() =
|
|
1085
1085
|
type React() =
|
1086
1086
|
inherit GeneratorExercise()
|
1087
1087
|
|
1088
|
-
|
1089
|
-
|
1090
|
-
member private __.RenderCells canonicalDataCase =
|
1088
|
+
let renderCells canonicalDataCase =
|
1091
1089
|
let reactorVar = sprintf "let %s = new %s()" "reactor" "Reactor"
|
1092
1090
|
let cellVars =
|
1093
1091
|
canonicalDataCase.Input.["cells"] :?> JArray
|
@@ -1110,56 +1108,87 @@ type React() =
|
|
1110
1108
|
|> Seq.toList
|
1111
1109
|
[ reactorVar ] @ cellVars
|
1112
1110
|
|
1113
|
-
|
1111
|
+
let renderExpectedCellValueOperation (op: JObject) =
|
1112
|
+
seq {
|
1113
|
+
let cellName = op.["cell"].ToObject<string>()
|
1114
|
+
let expectedValue = op.["value"].ToObject<int>()
|
1115
|
+
yield sprintf "%s.Value |> should equal %i" cellName expectedValue
|
1116
|
+
}
|
1117
|
+
|
1118
|
+
let renderExpectedCallbacks (jToken: JToken) =
|
1119
|
+
match jToken with
|
1120
|
+
| :? JObject as jObject ->
|
1121
|
+
seq {
|
1122
|
+
for child in jObject.Children<JProperty>() ->
|
1123
|
+
let callbackName = child.Name
|
1124
|
+
let callbackValue = child.Value |> string
|
1125
|
+
let callbackHandlerName = sprintf "%sHandler" callbackName
|
1126
|
+
|
1127
|
+
seq {
|
1128
|
+
yield sprintf "A.CallTo(fun() -> %s.Invoke(A<obj>.``_``, %s)).MustHaveHappenedOnceExactly() |> ignore" callbackHandlerName callbackValue
|
1129
|
+
yield sprintf "Fake.ClearRecordedCalls(%s) |> ignore" callbackHandlerName
|
1130
|
+
}
|
1131
|
+
} |> Seq.concat
|
1132
|
+
| _ -> Seq.empty
|
1133
|
+
|
1134
|
+
let renderExpectedCallbacksNotToBeCalled (jToken: JToken) =
|
1135
|
+
match jToken with
|
1136
|
+
| :? JArray as jArray ->
|
1137
|
+
jArray.ToObject<string list>()
|
1138
|
+
|> Seq.map (sprintf "A.CallTo(fun() -> %sHandler.Invoke(A<obj>.``_``, A<int>.``_``)).MustNotHaveHappened() |> ignore")
|
1139
|
+
| _ -> Seq.empty
|
1140
|
+
|
1141
|
+
let renderSetValueOperation (op: JObject) =
|
1142
|
+
seq {
|
1143
|
+
let cellName = op.["cell"].ToObject<string>()
|
1144
|
+
let cellValue = op.["value"].ToObject<int>()
|
1145
|
+
yield sprintf "%s.Value <- %i" cellName cellValue
|
1146
|
+
yield! renderExpectedCallbacks op.["expect_callbacks"]
|
1147
|
+
yield! renderExpectedCallbacksNotToBeCalled op.["expect_callbacks_not_to_be_called"]
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
let renderAddCallbackOperation (op: JObject) =
|
1151
|
+
seq {
|
1152
|
+
let callbackName = op.["name"].ToObject<string>()
|
1153
|
+
let cellName = op.["cell"].ToObject<string>()
|
1154
|
+
let callbackHandlerName = sprintf "%sHandler" callbackName
|
1155
|
+
yield sprintf "let %s = A.Fake<Handler<int>>()" callbackHandlerName
|
1156
|
+
yield sprintf "%s.Changed.AddHandler %s" cellName callbackHandlerName
|
1157
|
+
}
|
1158
|
+
|
1159
|
+
let renderRemoveCallbackOperation (op: JObject) =
|
1160
|
+
seq {
|
1161
|
+
let cellName = op.["cell"].ToObject<string>()
|
1162
|
+
let callbackName = op.["name"].ToObject<string>()
|
1163
|
+
yield sprintf "%s.Changed.RemoveHandler %sHandler" cellName callbackName
|
1164
|
+
}
|
1165
|
+
|
1166
|
+
let renderOperation (op: JObject) =
|
1167
|
+
let opType = op.["type"].ToObject<string>()
|
1168
|
+
match opType with
|
1169
|
+
| "expect_cell_value" -> renderExpectedCellValueOperation op
|
1170
|
+
| "set_value" -> renderSetValueOperation op
|
1171
|
+
| "add_callback" -> renderAddCallbackOperation op
|
1172
|
+
| "remove_callback" -> renderRemoveCallbackOperation op
|
1173
|
+
| _ -> failwith "Unknown operation type"
|
1174
|
+
|
1175
|
+
let renderOperations canonicalDataCase =
|
1114
1176
|
canonicalDataCase.Input.["operations"] :?> JArray
|
1115
|
-
|
1116
|
-
|
1117
|
-
// collect does it automatically for us
|
1118
|
-
// and every operation should emit seq<string>
|
1119
|
-
|> Seq.collect (fun (opToken: JToken) ->
|
1120
|
-
let op = opToken :?> JObject
|
1121
|
-
match op.["type"].ToObject<string>() with
|
1122
|
-
| "expect_cell_value" -> seq {
|
1123
|
-
let cellName = op.["cell"].ToObject<string>()
|
1124
|
-
let expectedValue = op.["value"].ToObject<int>()
|
1125
|
-
yield sprintf "%s.Value |> should equal %i" cellName expectedValue }
|
1126
|
-
| "set_value" -> seq {
|
1127
|
-
let cellName = op.["cell"].ToObject<string>()
|
1128
|
-
let cellValue = op.["value"].ToObject<int>()
|
1129
|
-
yield sprintf "%s.Value <- %i" cellName cellValue }
|
1130
|
-
| "add_callback" -> seq {
|
1131
|
-
let callbackName = op.["name"].ToObject<string>()
|
1132
|
-
let cellName = op.["cell"].ToObject<string>()
|
1133
|
-
let callback =
|
1134
|
-
if canonicalDataCase.Description.Contains("do not report") then
|
1135
|
-
"[value]"
|
1136
|
-
else
|
1137
|
-
sprintf "%s @ [value]" callbackName
|
1138
|
-
yield sprintf "let mutable %s = []" callbackName
|
1139
|
-
yield sprintf "let %sHandler = Handler<int>(fun _ value -> %s <- %s)" callbackName callbackName callback
|
1140
|
-
yield sprintf "%s.Changed.AddHandler %sHandler" cellName callbackName }
|
1141
|
-
| "expect_callback_values" -> seq {
|
1142
|
-
let callbackName = op.["callback"].ToObject<string>()
|
1143
|
-
let callbackValues = op.["values"].ToObject<string[]>()
|
1144
|
-
if callbackValues.Length = 0 then
|
1145
|
-
yield sprintf "%s |> should equal List.empty<int>" callbackName
|
1146
|
-
else
|
1147
|
-
yield sprintf "%s |> should equal %s" callbackName (formatList callbackValues) }
|
1148
|
-
| "remove_callback" -> seq {
|
1149
|
-
let cellName = op.["cell"].ToObject<string>()
|
1150
|
-
let callbackName = op.["name"].ToObject<string>()
|
1151
|
-
yield sprintf "%s.Changed.RemoveHandler %sHandler" cellName callbackName }
|
1152
|
-
| _ -> seq { yield "" }
|
1153
|
-
)
|
1177
|
+
|> Seq.cast<JObject>
|
1178
|
+
|> Seq.collect renderOperation
|
1154
1179
|
|> Seq.toList
|
1155
1180
|
|
1181
|
+
override __.PropertiesWithIdentifier _ = []
|
1182
|
+
|
1156
1183
|
override __.RenderAssert _ = []
|
1157
1184
|
|
1158
|
-
override
|
1159
|
-
let initialVars =
|
1160
|
-
let operations =
|
1185
|
+
override __.RenderArrange canonicalDataCase =
|
1186
|
+
let initialVars = renderCells canonicalDataCase
|
1187
|
+
let operations = renderOperations canonicalDataCase
|
1161
1188
|
initialVars @ operations
|
1162
1189
|
|
1190
|
+
override __.AdditionalNamespaces = ["FakeItEasy"]
|
1191
|
+
|
1163
1192
|
type Rectangles() =
|
1164
1193
|
inherit GeneratorExercise()
|
1165
1194
|
|
@@ -1330,6 +1359,12 @@ type Sieve() =
|
|
1330
1359
|
type SecretHandshake() =
|
1331
1360
|
inherit GeneratorExercise()
|
1332
1361
|
|
1362
|
+
type Series() =
|
1363
|
+
inherit GeneratorExercise()
|
1364
|
+
|
1365
|
+
override __.RenderExpected (_, _, value) =
|
1366
|
+
value |> Option.ofNonError |> formatValue |> parenthesizeOption
|
1367
|
+
|
1333
1368
|
type SpaceAge() =
|
1334
1369
|
inherit GeneratorExercise()
|
1335
1370
|
|