trackler 2.2.1.147 → 2.2.1.148
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/lib/trackler/version.rb +1 -1
- data/tracks/crystal/Makefile +1 -1
- data/tracks/crystal/exercises/acronym/spec/acronym_spec.cr +2 -6
- data/tracks/crystal/exercises/binary/spec/binary_spec.cr +1 -1
- data/tracks/crystal/exercises/difference-of-squares/spec/difference_of_squares_spec.cr +10 -14
- data/tracks/crystal/exercises/run-length-encoding/spec/run_length_encoding_spec.cr +29 -9
- data/tracks/crystal/generator/src/generators/acronym.cr +1 -1
- data/tracks/crystal/generator/src/generators/binary.cr +1 -1
- data/tracks/crystal/generator/src/generators/difference_of_squares.cr +6 -7
- data/tracks/crystal/generator/src/generators/run_length_encoding.cr +20 -10
- data/tracks/csharp/config.json +477 -477
- data/tracks/elixir/exercises/largest-series-product/example.exs +1 -1
- data/tracks/elm/exercises/phone-number/PhoneNumber.elm +1 -6
- data/tracks/elm/exercises/phone-number/tests/Tests.elm +22 -37
- data/tracks/elm/exercises/run-length-encoding/tests/Tests.elm +55 -31
- data/tracks/fsharp/generators/Exercise.fs +27 -6
- data/tracks/fsharp/generators/Generators.fs +37 -45
- data/tracks/fsharp/generators/Templates.fs +15 -44
- data/tracks/haskell/.travis.yml +1 -0
- data/tracks/haskell/bin/check-configlet-fmt.sh +42 -0
- data/tracks/haskell/config/maintainers.json +13 -13
- data/tracks/haskell/config.json +212 -250
- data/tracks/java/exercises/sublist/.meta/version +1 -1
- data/tracks/java/exercises/word-search/.meta/version +1 -1
- data/tracks/nim/config.json +10 -0
- data/tracks/nim/exercises/reverse-string/README.md +13 -0
- data/tracks/nim/exercises/reverse-string/example.nim +4 -0
- data/tracks/nim/exercises/reverse-string/reverse_string_test.nim +20 -0
- data/tracks/objective-c/config.json +10 -0
- data/tracks/objective-c/exercises/reverse-string/README.md +34 -0
- data/tracks/objective-c/exercises/reverse-string/ReverseStringExample.h +7 -0
- data/tracks/objective-c/exercises/reverse-string/ReverseStringExample.m +22 -0
- data/tracks/objective-c/exercises/reverse-string/ReverseStringTest.m +51 -0
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- data/tracks/ruby/config/maintainers.json +25 -25
- data/tracks/ruby/config.json +203 -371
- data/tracks/ruby/exercises/bob/.meta/.version +1 -1
- data/tracks/ruby/exercises/bob/.meta/generator/bob_case.rb +3 -2
- data/tracks/ruby/exercises/bob/.meta/solutions/bob.rb +3 -1
- data/tracks/ruby/exercises/bob/README.md +2 -0
- data/tracks/ruby/exercises/bob/bob_test.rb +27 -27
- data/tracks/ruby/exercises/hamming/RUNNING_TESTS.md +1 -1
- data/tracks/rust/.travis.yml +1 -0
- data/tracks/rust/_test/check-configlet-fmt.sh +37 -0
- data/tracks/rust/config/maintainers.json +23 -23
- data/tracks/rust/config.json +246 -246
- metadata +12 -3
- data/tracks/elm/exercises/run-length-encoding/RunLengthEncodingPropertyChecks.elm +0 -63
@@ -36,7 +36,7 @@ defmodule Series do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# Handle Enum.chunks -> Enum.chunk renaming.
|
39
|
-
if
|
39
|
+
if {:chunk, 3} not in Enum.__info__(:functions) do
|
40
40
|
defp chunk(coll, n, step), do: Enum.chunks(coll, n, step)
|
41
41
|
else
|
42
42
|
defp chunk(coll, n, step), do: Enum.chunk(coll, n, step)
|
@@ -1,11 +1,6 @@
|
|
1
|
-
module PhoneNumber exposing (getNumber
|
1
|
+
module PhoneNumber exposing (getNumber)
|
2
2
|
|
3
3
|
|
4
4
|
getNumber : String -> Maybe String
|
5
5
|
getNumber phoneNumber =
|
6
6
|
Debug.crash "Please implement this function"
|
7
|
-
|
8
|
-
|
9
|
-
prettyPrint : String -> Maybe String
|
10
|
-
prettyPrint input =
|
11
|
-
Debug.crash "Please implement this function"
|
@@ -1,67 +1,52 @@
|
|
1
1
|
module Tests exposing (..)
|
2
2
|
|
3
3
|
import Expect
|
4
|
-
import PhoneNumber exposing (getNumber
|
4
|
+
import PhoneNumber exposing (getNumber)
|
5
5
|
import Test exposing (..)
|
6
6
|
|
7
7
|
|
8
8
|
tests : Test
|
9
9
|
tests =
|
10
10
|
describe "PhoneNumber"
|
11
|
-
[ test "cleans number" <|
|
11
|
+
[ test "cleans the number" <|
|
12
12
|
\() -> Expect.equal (Just "2234567890") (getNumber "(223) 456-7890")
|
13
13
|
, skip <|
|
14
|
-
test "
|
15
|
-
\() -> Expect.equal Nothing (getNumber "")
|
16
|
-
, skip <|
|
17
|
-
test "cleans number with dots" <|
|
14
|
+
test "cleans numbers with dots" <|
|
18
15
|
\() -> Expect.equal (Just "2234567890") (getNumber "223.456.7890")
|
16
|
+
, skip <|
|
17
|
+
test "cleans numbers with multiple spaces" <|
|
18
|
+
\() -> Expect.equal (Just "2234567890") (getNumber "223 456 7890 ")
|
19
19
|
, skip <|
|
20
20
|
test "invalid when 9 digits" <|
|
21
21
|
\() -> Expect.equal Nothing (getNumber "223456789")
|
22
22
|
, skip <|
|
23
|
-
test "
|
24
|
-
\() -> Expect.equal
|
25
|
-
, skip <|
|
26
|
-
test "invalid when 12 digits" <|
|
27
|
-
\() -> Expect.equal Nothing (getNumber "223456789012")
|
23
|
+
test "invalid when 11 digits does not start with a 1" <|
|
24
|
+
\() -> Expect.equal Nothing (getNumber "22234567890")
|
28
25
|
, skip <|
|
29
|
-
test "valid when 11 digits and
|
26
|
+
test "valid when 11 digits and starting with 1" <|
|
30
27
|
\() -> Expect.equal (Just "2234567890") (getNumber "12234567890")
|
31
28
|
, skip <|
|
32
|
-
test "
|
33
|
-
\() -> Expect.equal Nothing (getNumber "22234567890")
|
34
|
-
, skip <|
|
35
|
-
test "valid when 11 digits and first is 1 with punctuation" <|
|
29
|
+
test "valid when 11 digits and starting with 1 even with punctuation" <|
|
36
30
|
\() -> Expect.equal (Just "2234567890") (getNumber "+1 (223) 456-7890")
|
31
|
+
, skip <|
|
32
|
+
test "invalid when more than 11 digits" <|
|
33
|
+
\() -> Expect.equal Nothing (getNumber "321234567890")
|
37
34
|
, skip <|
|
38
35
|
test "invalid with letters" <|
|
39
|
-
\() -> Expect.equal Nothing (getNumber "
|
36
|
+
\() -> Expect.equal Nothing (getNumber "123-abc-7890")
|
40
37
|
, skip <|
|
41
|
-
test "invalid with
|
42
|
-
\() -> Expect.equal Nothing (getNumber "
|
38
|
+
test "invalid with punctuations" <|
|
39
|
+
\() -> Expect.equal Nothing (getNumber "123-@:!-7890")
|
43
40
|
, skip <|
|
44
|
-
test "invalid
|
45
|
-
\() -> Expect.equal Nothing (getNumber "(123) 456-7890")
|
46
|
-
, skip <|
|
47
|
-
test "invalid when area code starts with 0" <|
|
41
|
+
test "invalid if area code starts with 0" <|
|
48
42
|
\() -> Expect.equal Nothing (getNumber "(023) 456-7890")
|
49
43
|
, skip <|
|
50
|
-
test "invalid
|
51
|
-
\() -> Expect.equal Nothing (getNumber "(
|
44
|
+
test "invalid if area code starts with 1" <|
|
45
|
+
\() -> Expect.equal Nothing (getNumber "(123) 456-7890")
|
52
46
|
, skip <|
|
53
|
-
test "invalid
|
47
|
+
test "invalid if exchange code starts with 0" <|
|
54
48
|
\() -> Expect.equal Nothing (getNumber "(223) 056-7890")
|
55
49
|
, skip <|
|
56
|
-
test "invalid
|
57
|
-
\() -> Expect.equal Nothing (getNumber "
|
58
|
-
, skip <|
|
59
|
-
test "invalid when no digits present" <|
|
60
|
-
\() -> Expect.equal Nothing (getNumber " (-) ")
|
61
|
-
, skip <|
|
62
|
-
test "pretty print" <|
|
63
|
-
\() -> Expect.equal (Just "(223) 456-7890") (prettyPrint "2234567890")
|
64
|
-
, skip <|
|
65
|
-
test "pretty print with full us phone number" <|
|
66
|
-
\() -> Expect.equal (Just "(223) 456-7890") (prettyPrint "12234567890")
|
50
|
+
test "invalid if exchange code starts with 1" <|
|
51
|
+
\() -> Expect.equal Nothing (getNumber "(223) 156-7890")
|
67
52
|
]
|
@@ -10,35 +10,59 @@ tests =
|
|
10
10
|
describe "RunLengthEncoding"
|
11
11
|
[ test "the solution is for the correct version of the test" <|
|
12
12
|
\() -> Expect.equal 2 version
|
13
|
-
,
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
Expect.equal "
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
13
|
+
, describe "run-length encode a string"
|
14
|
+
[ test "empty string" <|
|
15
|
+
\() -> Expect.equal "" (encode "")
|
16
|
+
, skip <|
|
17
|
+
test "single characters only are encoded without count" <|
|
18
|
+
\() -> Expect.equal "XYZ" (encode "XYZ")
|
19
|
+
, skip <|
|
20
|
+
test "string with no single characters" <|
|
21
|
+
\() -> Expect.equal "2A3B4C" (encode "AABBBCCCC")
|
22
|
+
, skip <|
|
23
|
+
test "single characters mixed with repeated characters" <|
|
24
|
+
\() ->
|
25
|
+
Expect.equal "12WB12W3B24WB"
|
26
|
+
(encode "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB")
|
27
|
+
, skip <|
|
28
|
+
test "multiple whitespace mixed in string" <|
|
29
|
+
\() -> Expect.equal "2 hs2q q2w2 " (encode " hsqq qww ")
|
30
|
+
, skip <|
|
31
|
+
test "lowercase characters" <|
|
32
|
+
\() -> Expect.equal "2a3b4c" (encode "aabbbcccc")
|
33
|
+
]
|
34
|
+
, describe "run-length decode a string"
|
35
|
+
[ skip <|
|
36
|
+
test "empty string" <|
|
37
|
+
\() -> Expect.equal "" (decode "")
|
38
|
+
, skip <|
|
39
|
+
test "single characters only" <|
|
40
|
+
\() -> Expect.equal "XYZ" (decode "XYZ")
|
41
|
+
, skip <|
|
42
|
+
test "string with no single characters" <|
|
43
|
+
\() -> Expect.equal "AABBBCCCC" (decode "2A3B4C")
|
44
|
+
, skip <|
|
45
|
+
test "single characters with repeated characters" <|
|
46
|
+
\() ->
|
47
|
+
Expect.equal "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"
|
48
|
+
(decode "12WB12W3B24WB")
|
49
|
+
, skip <|
|
50
|
+
test "multiple whitespace mixed in string" <|
|
51
|
+
\() -> Expect.equal " hsqq qww " (decode "2 hs2q q2w2 ")
|
52
|
+
, skip <|
|
53
|
+
test "lower case string" <|
|
54
|
+
\() -> Expect.equal "" (decode "")
|
55
|
+
, skip <|
|
56
|
+
test "with a x10 value" <|
|
57
|
+
\() ->
|
58
|
+
Expect.equal "WWWWWWWWWW"
|
59
|
+
(decode "10W")
|
60
|
+
]
|
61
|
+
, describe "encode and then decode"
|
62
|
+
[ skip <|
|
63
|
+
test "encode followed by decode gives original string" <|
|
64
|
+
\() ->
|
65
|
+
Expect.equal "zzz ZZ zZ"
|
66
|
+
(decode (encode "zzz ZZ zZ"))
|
67
|
+
]
|
44
68
|
]
|
@@ -11,6 +11,11 @@ open Templates
|
|
11
11
|
open CanonicalData
|
12
12
|
open Track
|
13
13
|
|
14
|
+
let [<Literal>] private AssertEmptyTemplate = "AssertEmpty"
|
15
|
+
let [<Literal>] private AssertEqualTemplate = "AssertEqual"
|
16
|
+
let [<Literal>] private AssertEqualWithinTemplate = "AssertEqualWithin"
|
17
|
+
let [<Literal>] private AssertThrowsTemplate = "AssertThrows"
|
18
|
+
|
14
19
|
let private exerciseNameFromType (exerciseType: Type) = exerciseType.Name.Kebaberize()
|
15
20
|
|
16
21
|
[<AbstractClass>]
|
@@ -109,9 +114,25 @@ type GeneratorExercise() =
|
|
109
114
|
let expectedHasIdentifier = List.contains "expected" (this.PropertiesWithIdentifier canonicalDataCase)
|
110
115
|
|
111
116
|
if expectedIsArray && expectedIsEmpty && not expectedHasIdentifier then
|
112
|
-
|
117
|
+
AssertEmptyTemplate
|
113
118
|
else
|
114
|
-
|
119
|
+
AssertEqualTemplate
|
120
|
+
|
121
|
+
member __.RenderAssertEmpty sut expected =
|
122
|
+
{ Sut = sut; Expected = expected }
|
123
|
+
|> renderTemplate AssertEmptyTemplate
|
124
|
+
|
125
|
+
member __.RenderAssertEqual sut expected =
|
126
|
+
{ Sut = sut; Expected = expected }
|
127
|
+
|> renderTemplate AssertEqualTemplate
|
128
|
+
|
129
|
+
member __.RenderAssertEqualWithin sut expected =
|
130
|
+
{ Sut = sut; Expected = expected }
|
131
|
+
|> renderTemplate AssertEqualWithinTemplate
|
132
|
+
|
133
|
+
member __.RenderAssertThrows sut expected =
|
134
|
+
{ Sut = sut; Expected = expected }
|
135
|
+
|> renderTemplate AssertThrowsTemplate
|
115
136
|
|
116
137
|
default __.TestFileFormat = TestFileFormat.Module
|
117
138
|
|
@@ -120,21 +141,21 @@ type GeneratorExercise() =
|
|
120
141
|
member this.Render canonicalData =
|
121
142
|
canonicalData
|
122
143
|
|> this.ToTestFile
|
123
|
-
|>
|
144
|
+
|> renderTemplate this.TestFileTemplate
|
124
145
|
|
125
146
|
member this.RenderTestMethod (index, canonicalDataCase) =
|
126
147
|
let template = this.TestMethodTemplate (index, canonicalDataCase)
|
127
148
|
|
128
149
|
(index, canonicalDataCase)
|
129
150
|
|> this.ToTestMethod
|
130
|
-
|>
|
151
|
+
|> renderTemplate template
|
131
152
|
|
132
153
|
member this.RenderTestMethodBody canonicalDataCase =
|
133
154
|
let template = this.TestMethodBodyTemplate canonicalDataCase
|
134
155
|
|
135
156
|
canonicalDataCase
|
136
157
|
|> this.ToTestMethodBody
|
137
|
-
|>
|
158
|
+
|> renderTemplate template
|
138
159
|
|
139
160
|
default this.TestMethodName canonicalDataCase =
|
140
161
|
match this.UseFullMethodName canonicalDataCase with
|
@@ -213,7 +234,7 @@ type GeneratorExercise() =
|
|
213
234
|
|
214
235
|
canonicalDataCase
|
215
236
|
|> this.ToTestMethodBodyAssert
|
216
|
-
|>
|
237
|
+
|> renderTemplate template
|
217
238
|
|> List.singleton
|
218
239
|
|
219
240
|
default this.RenderSut canonicalDataCase =
|
@@ -28,20 +28,18 @@ type Allergies() =
|
|
28
28
|
|
29
29
|
let renderAllergenEnum (jToken: JToken) = Obj.renderEnum "Allergen" jToken
|
30
30
|
|
31
|
-
|
31
|
+
member this.RenderAllergicToAssert canonicalDataCase (jToken: JToken) =
|
32
32
|
let substance = renderAllergenEnum jToken.["substance"]
|
33
33
|
let score = canonicalDataCase.Input.["score"].ToObject<int>()
|
34
34
|
let sut = sprintf "allergicTo %d %s" score substance
|
35
35
|
let expected = jToken.Value<bool>("result") |> Bool.render
|
36
|
-
|
37
|
-
{ Sut = sut; Expected = expected }
|
38
|
-
|> renderPartialTemplate "AssertEqual"
|
36
|
+
this.RenderAssertEqual sut expected
|
39
37
|
|
40
|
-
override
|
38
|
+
override this.RenderAssert canonicalDataCase =
|
41
39
|
match canonicalDataCase.Property with
|
42
40
|
| "allergicTo" ->
|
43
41
|
canonicalDataCase.Expected
|
44
|
-
|> Seq.map (
|
42
|
+
|> Seq.map (this.RenderAllergicToAssert canonicalDataCase)
|
45
43
|
|> Seq.toList
|
46
44
|
| _ ->
|
47
45
|
base.RenderAssert canonicalDataCase
|
@@ -97,7 +95,7 @@ type BinarySearch() =
|
|
97
95
|
type BinarySearchTree() =
|
98
96
|
inherit GeneratorExercise()
|
99
97
|
|
100
|
-
|
98
|
+
member this.RenderAssertions previousPaths (tree: JToken) =
|
101
99
|
let previousPath = previousPaths |> List.rev |> String.concat " |> "
|
102
100
|
let rootPath = List.length previousPaths = 1
|
103
101
|
|
@@ -108,30 +106,30 @@ type BinarySearchTree() =
|
|
108
106
|
match data.Type with
|
109
107
|
| JTokenType.Null ->
|
110
108
|
let expected = if rootPath then failwith "Invalid data" else "None"
|
111
|
-
[ sprintf "%s |> %s
|
109
|
+
[ this.RenderAssertEqual (sprintf "%s |> %s" previousPath dataPath) expected ]
|
112
110
|
| _ ->
|
113
111
|
let expected = if rootPath then string data else sprintf "(Some %s)" (string data)
|
114
|
-
[ sprintf "%s |> %s
|
112
|
+
[ this.RenderAssertEqual (sprintf "%s |> %s" previousPath dataPath) expected ]
|
115
113
|
|
116
114
|
let renderNodeAssertions nodeName (node: JToken) =
|
117
115
|
let nodePath = if rootPath then nodeName else sprintf "Option.bind %s" nodeName
|
118
116
|
|
119
117
|
match node.Type with
|
120
118
|
| JTokenType.Null ->
|
121
|
-
[ sprintf "%s |> %s
|
119
|
+
[ this.RenderAssertEqual (sprintf "%s |> %s" previousPath nodePath) "None" ]
|
122
120
|
| _ ->
|
123
|
-
|
121
|
+
this.RenderAssertions (nodePath :: previousPaths) node
|
124
122
|
|
125
123
|
[ renderDataAssertions
|
126
124
|
renderNodeAssertions "left" tree.["left"]
|
127
125
|
renderNodeAssertions "right" tree.["right"] ]
|
128
126
|
|> List.concat
|
129
127
|
|
130
|
-
override
|
128
|
+
override this.RenderAssert canonicalDataCase =
|
131
129
|
match canonicalDataCase.Property with
|
132
130
|
| "data" ->
|
133
131
|
canonicalDataCase.Expected
|
134
|
-
|>
|
132
|
+
|> this.RenderAssertions ["treeData"]
|
135
133
|
| _ -> base.RenderAssert canonicalDataCase
|
136
134
|
|
137
135
|
override __.RenderInput (_, _, value) =
|
@@ -211,8 +209,7 @@ type CircularBuffer() =
|
|
211
209
|
|
212
210
|
override __.RenderAssert _ = []
|
213
211
|
|
214
|
-
member
|
215
|
-
sprintf "(fun () -> %s |> ignore) |> should throw typeof<Exception>" command
|
212
|
+
member this.ExceptionCheck command = this.RenderAssertThrows command typeof<Exception>.Name
|
216
213
|
|
217
214
|
override this.RenderArrange canonicalDataCase =
|
218
215
|
seq {
|
@@ -243,16 +240,14 @@ type CircularBuffer() =
|
|
243
240
|
yield sprintf "let (val%i, _) = %s" ind command
|
244
241
|
else
|
245
242
|
yield sprintf "let (val%i, buffer%i) = %s" ind ind command
|
246
|
-
yield sprintf "val%i
|
243
|
+
yield this.RenderAssertEqual (sprintf "val%i" ind) (string expected)
|
247
244
|
| "overwrite" ->
|
248
245
|
yield sprintf "let buffer%i = forceWrite %i buffer%i" ind (dict.["item"].ToObject<int>()) (ind-1)
|
249
246
|
| "clear" ->
|
250
247
|
yield sprintf "let buffer%i = clear buffer%i" ind (ind - 1)
|
251
248
|
| _ -> ()
|
252
249
|
ind <- ind + 1
|
253
|
-
|
254
|
-
}
|
255
|
-
|> Seq.toList
|
250
|
+
} |> Seq.toList
|
256
251
|
|
257
252
|
type Clock() =
|
258
253
|
inherit GeneratorExercise()
|
@@ -316,12 +311,11 @@ type ComplexNumbers() =
|
|
316
311
|
| JTokenType.Integer -> sprintf "%d.0" (value.ToObject<int>())
|
317
312
|
| _ -> base.RenderValue (canonicalDataCase, key, value)
|
318
313
|
|
319
|
-
override
|
314
|
+
override this.RenderAssert canonicalDataCase =
|
320
315
|
match canonicalDataCase.Expected.Type with
|
321
316
|
| JTokenType.Array ->
|
322
317
|
let renderAssertion testedFunction expected =
|
323
|
-
|
324
|
-
|> renderPartialTemplate "AssertEqualWithin"
|
318
|
+
this.RenderAssertEqualWithin (sprintf "%s sut" testedFunction) expected
|
325
319
|
|
326
320
|
[ canonicalDataCase.Expected.[0] |> renderNumber |> renderAssertion "real"
|
327
321
|
canonicalDataCase.Expected.[1] |> renderNumber |> renderAssertion "imaginary" ]
|
@@ -451,7 +445,7 @@ type DiffieHellman() =
|
|
451
445
|
List.append arrange ["let privateKeys = [for _ in 0 .. 10 -> privateKey p]" ]
|
452
446
|
| _ -> arrange
|
453
447
|
|
454
|
-
override
|
448
|
+
override this.RenderAssert canonicalDataCase =
|
455
449
|
match canonicalDataCase.Property with
|
456
450
|
| "privateKeyIsInRange" ->
|
457
451
|
let greaterThan = canonicalDataCase.Expected.["greaterThan"].ToObject<int>()
|
@@ -460,9 +454,9 @@ type DiffieHellman() =
|
|
460
454
|
[ sprintf "privateKeys |> List.iter (fun x -> x |> should be (greaterThan %dI))" greaterThan;
|
461
455
|
sprintf "privateKeys |> List.iter (fun x -> x |> should be (lessThan %s))" lessThan ]
|
462
456
|
| "privateKeyIsRandom" ->
|
463
|
-
[ "List.distinct privateKeys |> List.length
|
457
|
+
[ this.RenderAssertEqual "List.distinct privateKeys |> List.length" "(List.length privateKeys)" ]
|
464
458
|
| "keyExchange" ->
|
465
|
-
[ "secretA
|
459
|
+
[ this.RenderAssertEqual "secretA" "secretB" ]
|
466
460
|
| _ -> base.RenderAssert canonicalDataCase
|
467
461
|
|
468
462
|
override __.MapCanonicalDataCase canonicalDataCase =
|
@@ -647,7 +641,7 @@ type Grep() =
|
|
647
641
|
|
648
642
|
override __.RenderExpected (_, _, value) = List.renderMultiLine value |> indentExpected
|
649
643
|
|
650
|
-
override __.RenderSetup _ =
|
644
|
+
override __.RenderSetup _ = renderTemplate "Generators/GrepSetup" Map.empty<string, obj>
|
651
645
|
|
652
646
|
override __.RenderArrange canonicalDataCase =
|
653
647
|
base.RenderArrange canonicalDataCase @ [""; "createFiles() |> ignore"]
|
@@ -1046,13 +1040,6 @@ type React() =
|
|
1046
1040
|
)
|
1047
1041
|
|> Seq.toList
|
1048
1042
|
[ reactorVar ] @ cellVars
|
1049
|
-
|
1050
|
-
let renderExpectedCellValueOperation (op: JToken) =
|
1051
|
-
seq {
|
1052
|
-
let cellName = op.["cell"].ToObject<string>()
|
1053
|
-
let expectedValue = op.["value"].ToObject<int>()
|
1054
|
-
yield sprintf "%s.Value |> should equal %i" cellName expectedValue
|
1055
|
-
}
|
1056
1043
|
|
1057
1044
|
let renderExpectedCallbacks (jToken: JToken) =
|
1058
1045
|
match jToken with
|
@@ -1101,28 +1088,35 @@ type React() =
|
|
1101
1088
|
let callbackName = op.["name"].ToObject<string>()
|
1102
1089
|
yield sprintf "%s.Changed.RemoveHandler %sHandler" cellName callbackName
|
1103
1090
|
}
|
1091
|
+
|
1092
|
+
member this.RenderExpectedCellValueOperation (op: JToken) =
|
1093
|
+
seq {
|
1094
|
+
let cellName = op.["cell"].ToObject<string>()
|
1095
|
+
let expectedValue = op.["value"].ToObject<string>()
|
1096
|
+
yield this.RenderAssertEqual (sprintf "%s.Value" cellName) expectedValue
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
member this.RenderOperations canonicalDataCase =
|
1100
|
+
canonicalDataCase.Input.["operations"]
|
1101
|
+
|> Seq.collect this.renderOperation
|
1102
|
+
|> Seq.toList
|
1104
1103
|
|
1105
|
-
|
1104
|
+
member this.renderOperation (op: JToken) =
|
1106
1105
|
let opType = op.["type"].ToObject<string>()
|
1107
1106
|
match opType with
|
1108
|
-
| "expect_cell_value" ->
|
1107
|
+
| "expect_cell_value" -> this.RenderExpectedCellValueOperation op
|
1109
1108
|
| "set_value" -> renderSetValueOperation op
|
1110
1109
|
| "add_callback" -> renderAddCallbackOperation op
|
1111
1110
|
| "remove_callback" -> renderRemoveCallbackOperation op
|
1112
1111
|
| _ -> failwith "Unknown operation type"
|
1113
1112
|
|
1114
|
-
let renderOperations canonicalDataCase =
|
1115
|
-
canonicalDataCase.Input.["operations"]
|
1116
|
-
|> Seq.collect renderOperation
|
1117
|
-
|> Seq.toList
|
1118
|
-
|
1119
1113
|
override __.PropertiesWithIdentifier _ = []
|
1120
1114
|
|
1121
1115
|
override __.RenderAssert _ = []
|
1122
1116
|
|
1123
|
-
override
|
1117
|
+
override this.RenderArrange canonicalDataCase =
|
1124
1118
|
let initialVars = renderCells canonicalDataCase
|
1125
|
-
let operations =
|
1119
|
+
let operations = this.RenderOperations canonicalDataCase
|
1126
1120
|
initialVars @ operations
|
1127
1121
|
|
1128
1122
|
override __.AdditionalNamespaces = ["FakeItEasy"]
|
@@ -1170,9 +1164,7 @@ type RobotSimulator() =
|
|
1170
1164
|
override this.RenderAssert canonicalDataCase =
|
1171
1165
|
let renderAssertWithProperty prop =
|
1172
1166
|
let expected = this.RenderExpected (canonicalDataCase, "expected", canonicalDataCase.Expected)
|
1173
|
-
|
1174
|
-
{ Sut = sprintf "sut.%s" prop; Expected = expected }
|
1175
|
-
|> renderPartialTemplate "AssertEqual"
|
1167
|
+
this.RenderAssertEqual (sprintf "sut.%s" prop) expected
|
1176
1168
|
|
1177
1169
|
match parseInput canonicalDataCase.Expected with
|
1178
1170
|
| None, Some _ -> [renderAssertWithProperty "position"]
|
@@ -2,63 +2,34 @@ module Generators.Templates
|
|
2
2
|
|
3
3
|
open System.IO
|
4
4
|
open System.Collections.Generic
|
5
|
-
open System.Reflection
|
6
5
|
open FSharp.Reflection
|
7
6
|
open DotLiquid
|
8
7
|
open DotLiquid.FileSystems
|
9
8
|
open Rendering
|
10
9
|
|
11
10
|
type OutputFilter() =
|
12
|
-
static member Format (input: string) = Obj.render input
|
13
|
-
|
14
11
|
static member Indent (input: string) = String.indent 1 input
|
15
12
|
|
16
|
-
let private
|
17
|
-
Template.
|
18
|
-
|
13
|
+
let private initTemplate() =
|
14
|
+
Template.FileSystem <- LocalFileSystem(Path.GetFullPath("./Templates"))
|
15
|
+
|
16
|
+
Template.RegisterFilter(OutputFilter().GetType()) |> ignore
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
let properties = templateDataType.GetProperties(BindingFlags.Instance ||| BindingFlags.Public)
|
25
|
-
Template.RegisterSafeType(templateDataType, [| for p in properties -> p.Name |])
|
26
|
-
registrations.[templateDataType] <- true
|
27
|
-
for p in properties do registerTypeTree p.PropertyType
|
28
|
-
elif templateDataType.IsGenericType then
|
29
|
-
let t = templateDataType.GetGenericTypeDefinition()
|
30
|
-
if t = typedefof<seq<_>> || t = typedefof<list<_>> then
|
31
|
-
registrations.[templateDataType] <- true
|
32
|
-
registerTypeTree (templateDataType.GetGenericArguments().[0])
|
33
|
-
elif t = typedefof<IDictionary<_,_>> || t = typedefof<Map<_,_>> then
|
34
|
-
registrations.[templateDataType] <- true
|
35
|
-
registerTypeTree (templateDataType.GetGenericArguments().[0])
|
36
|
-
registerTypeTree (templateDataType.GetGenericArguments().[1])
|
37
|
-
elif t = typedefof<option<_>> then
|
38
|
-
Template.RegisterSafeType(templateDataType, [|"Value"; "IsSome"; "IsNone";|])
|
39
|
-
registrations.[templateDataType] <- true
|
40
|
-
registerTypeTree (templateDataType.GetGenericArguments().[0])
|
41
|
-
elif templateDataType.IsArray then
|
42
|
-
registrations.[templateDataType] <- true
|
43
|
-
registerTypeTree (templateDataType.GetElementType())
|
44
|
-
else
|
45
|
-
let properties = templateDataType.GetProperties(BindingFlags.Instance ||| BindingFlags.Public)
|
46
|
-
Template.RegisterSafeType(templateDataType, [| for p in properties -> p.Name |])
|
47
|
-
registrations.[templateDataType] <- true
|
48
|
-
for p in properties do registerTypeTree p.PropertyType
|
18
|
+
Template.RegisterSafeType(typeof<TestMethodBodyAssert>, [| "Sut"; "Expected" |])
|
19
|
+
Template.RegisterSafeType(typeof<TestMethodBody>, [| "Arrange"; "Assert" |])
|
20
|
+
Template.RegisterSafeType(typeof<TestMethod>, [| "Skip"; "Name"; "Body" |])
|
21
|
+
Template.RegisterSafeType(typeof<TestFile>, [| "Version"; "TestModuleName"; "TestedModuleName"; "Namespaces"; "Setup"; "Methods" |])
|
49
22
|
|
50
23
|
let private hashFromData (data: obj) =
|
51
24
|
match FSharpType.IsRecord (data.GetType()) with
|
52
25
|
| true -> Hash.FromAnonymousObject(data)
|
53
26
|
| false -> Hash.FromDictionary(data :?> IDictionary<string, obj>)
|
54
27
|
|
55
|
-
let
|
56
|
-
|
57
|
-
|
58
|
-
let parsedTemplate = Template.Parse template
|
59
|
-
let hash = hashFromData data
|
60
|
-
parsedTemplate.Render(hash)
|
28
|
+
let renderTemplate =
|
29
|
+
initTemplate()
|
61
30
|
|
62
|
-
|
63
|
-
|
64
|
-
|
31
|
+
fun (name: string) (data: obj) ->
|
32
|
+
let template = sprintf "{%% include \"%s\" %%}" name
|
33
|
+
let parsedTemplate = Template.Parse template
|
34
|
+
let hashedData = hashFromData data
|
35
|
+
parsedTemplate.Render hashedData
|
data/tracks/haskell/.travis.yml
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# This ensures that config.json and config/maintainers.json are compatible
|
4
|
+
# with the output of configlet fmt.
|
5
|
+
|
6
|
+
repo=$(cd "$(dirname "$0")/.." && pwd)
|
7
|
+
configlet="${repo}/bin/configlet"
|
8
|
+
|
9
|
+
if [ ! -x "$configlet" ]; then
|
10
|
+
# Try it from the path.
|
11
|
+
configlet=configlet
|
12
|
+
fi
|
13
|
+
|
14
|
+
c="${repo}/config.json"
|
15
|
+
m="${repo}/config/maintainers.json"
|
16
|
+
|
17
|
+
md5() {
|
18
|
+
md5sum $1 | cut -d' ' -f1
|
19
|
+
}
|
20
|
+
|
21
|
+
# before S sum
|
22
|
+
bcs=$(md5 $c)
|
23
|
+
bms=$(md5 $m)
|
24
|
+
|
25
|
+
cfg=$($configlet fmt .)
|
26
|
+
if [ $? != 0 ]; then
|
27
|
+
echo "configlet fmt returned non-0 exit code with output:"
|
28
|
+
echo $cfg
|
29
|
+
exit 1
|
30
|
+
fi
|
31
|
+
|
32
|
+
# after S sum
|
33
|
+
acs=$(md5 $c)
|
34
|
+
ams=$(md5 $m)
|
35
|
+
|
36
|
+
if [ $bcs != $acs -o $bms != $ams ]; then
|
37
|
+
echo "configlet fmt:"
|
38
|
+
echo $cfg
|
39
|
+
echo "Please update the PR to incorporate those changes."
|
40
|
+
exit 1
|
41
|
+
fi
|
42
|
+
exit 0
|