trackler 2.2.1.88 → 2.2.1.89
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/problem-specifications/exercises/bowling/canonical-data.json +95 -39
- data/problem-specifications/exercises/gigasecond/canonical-data.json +17 -7
- data/problem-specifications/exercises/pangram/canonical-data.json +32 -12
- data/problem-specifications/exercises/say/canonical-data.json +47 -17
- data/problem-specifications/exercises/sum-of-multiples/canonical-data.json +54 -28
- data/problem-specifications/exercises/triangle/canonical-data.json +52 -18
- data/problem-specifications/exercises/two-bucket/canonical-data.json +38 -26
- data/problem-specifications/exercises/two-fer/canonical-data.json +14 -8
- data/problem-specifications/exercises/word-count/canonical-data.json +35 -13
- data/problem-specifications/exercises/wordy/canonical-data.json +50 -18
- data/tracks/bash/exercises/leap/.meta/version +1 -0
- data/tracks/bash/exercises/leap/example.sh +9 -9
- data/tracks/bash/exercises/leap/leap_test.sh +17 -33
- data/tracks/ceylon/exercises/anagram/source/anagram/AnagramTest.ceylon +1 -1
- data/tracks/ceylon/exercises/bracket-push/source/bracketpush/BracketsTest.ceylon +1 -1
- data/tracks/ceylon/exercises/rna-transcription/source/rnatranscription/RNATest.ceylon +2 -1
- data/tracks/fsharp/build.cake +2 -7
- data/tracks/fsharp/exercises/acronym/AcronymTest.fs +1 -1
- data/tracks/fsharp/exercises/all-your-base/AllYourBase.fs +1 -1
- data/tracks/fsharp/exercises/all-your-base/AllYourBaseTest.fs +43 -43
- data/tracks/fsharp/exercises/all-your-base/Example.fs +5 -5
- data/tracks/fsharp/exercises/allergies/AllergiesTest.fs +1 -1
- data/tracks/fsharp/exercises/alphametics/AlphameticsTest.fs +19 -1
- data/tracks/fsharp/exercises/alphametics/Example.fs +53 -34
- data/tracks/fsharp/exercises/anagram/AnagramTest.fs +1 -1
- data/tracks/fsharp/exercises/atbash-cipher/AtbashCipherTest.fs +1 -1
- data/tracks/fsharp/exercises/beer-song/BeerSongTest.fs +1 -1
- data/tracks/fsharp/exercises/binary-search/BinarySearchTest.fs +1 -1
- data/tracks/fsharp/exercises/bob/BobTest.fs +1 -1
- data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +1 -1
- data/tracks/fsharp/exercises/bracket-push/BracketPushTest.fs +1 -1
- data/tracks/fsharp/exercises/change/ChangeTest.fs +1 -1
- data/tracks/fsharp/exercises/collatz-conjecture/CollatzConjectureTest.fs +1 -1
- data/tracks/fsharp/exercises/connect/ConnectTest.fs +1 -1
- data/tracks/fsharp/exercises/crypto-square/CryptoSquareTest.fs +1 -1
- data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquaresTest.fs +1 -1
- data/tracks/fsharp/exercises/dominoes/DominoesTest.fs +25 -25
- data/tracks/fsharp/exercises/etl/EtlTest.fs +8 -8
- data/tracks/fsharp/exercises/isbn-verifier/IsbnVerifierTest.fs +5 -1
- data/tracks/fsharp/exercises/luhn/LuhnTest.fs +1 -1
- data/tracks/fsharp/exercises/meetup/Example.fs +11 -11
- data/tracks/fsharp/exercises/meetup/Meetup.fs +2 -2
- data/tracks/fsharp/exercises/meetup/MeetupTest.fs +96 -96
- data/tracks/fsharp/exercises/robot-simulator/Example.fs +21 -21
- data/tracks/fsharp/exercises/robot-simulator/RobotSimulator.fs +5 -5
- data/tracks/fsharp/exercises/robot-simulator/RobotSimulatorTest.fs +78 -96
- data/tracks/fsharp/generators/CanonicalData.fs +50 -4
- data/tracks/fsharp/generators/Common.fs +4 -13
- data/tracks/fsharp/generators/Exercise.fs +31 -15
- data/tracks/fsharp/generators/Generators.fs +76 -111
- data/tracks/haskell/exercises/alphametics/package.yaml +1 -1
- data/tracks/haskell/exercises/alphametics/test/Tests.hs +5 -0
- data/tracks/haskell/exercises/bowling/package.yaml +1 -1
- data/tracks/haskell/exercises/pangram/package.yaml +1 -1
- data/tracks/haskell/exercises/say/package.yaml +1 -1
- data/tracks/haskell/exercises/sum-of-multiples/package.yaml +1 -1
- data/tracks/haskell/exercises/word-count/package.yaml +1 -1
- data/tracks/haskell/exercises/wordy/package.yaml +1 -1
- data/tracks/java/exercises/nucleotide-count/.meta/hints.md +58 -0
- data/tracks/java/exercises/nucleotide-count/README.md +62 -0
- metadata +4 -2
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
module RobotSimulator
|
|
2
2
|
|
|
3
|
-
type
|
|
4
|
-
type
|
|
3
|
+
type Direction = North | East | South | West
|
|
4
|
+
type Position = int * int
|
|
5
5
|
|
|
6
|
-
type Robot = {
|
|
6
|
+
type Robot = { direction: Direction; position: Position }
|
|
7
7
|
|
|
8
|
-
let
|
|
8
|
+
let create bearing position = { direction = bearing; position = position }
|
|
9
9
|
|
|
10
10
|
let turnLeft robot =
|
|
11
|
-
match robot.
|
|
12
|
-
| North -> { robot with
|
|
13
|
-
| East -> { robot with
|
|
14
|
-
| South -> { robot with
|
|
15
|
-
| West -> { robot with
|
|
11
|
+
match robot.direction with
|
|
12
|
+
| North -> { robot with direction = West }
|
|
13
|
+
| East -> { robot with direction = North }
|
|
14
|
+
| South -> { robot with direction = East }
|
|
15
|
+
| West -> { robot with direction = South }
|
|
16
16
|
|
|
17
17
|
let turnRight robot =
|
|
18
|
-
match robot.
|
|
19
|
-
| North -> { robot with
|
|
20
|
-
| East -> { robot with
|
|
21
|
-
| South -> { robot with
|
|
22
|
-
| West -> { robot with
|
|
18
|
+
match robot.direction with
|
|
19
|
+
| North -> { robot with direction = East }
|
|
20
|
+
| East -> { robot with direction = South }
|
|
21
|
+
| South -> { robot with direction = West }
|
|
22
|
+
| West -> { robot with direction = North }
|
|
23
23
|
|
|
24
24
|
let advance robot =
|
|
25
|
-
let (x, y) = robot.
|
|
25
|
+
let (x, y) = robot.position
|
|
26
26
|
|
|
27
|
-
match robot.
|
|
28
|
-
| North -> { robot with
|
|
29
|
-
| East -> { robot with
|
|
30
|
-
| South -> { robot with
|
|
31
|
-
| West -> { robot with
|
|
27
|
+
match robot.direction with
|
|
28
|
+
| North -> { robot with position = (x , y + 1) }
|
|
29
|
+
| East -> { robot with position = (x + 1, y ) }
|
|
30
|
+
| South -> { robot with position = (x , y - 1) }
|
|
31
|
+
| West -> { robot with position = (x - 1, y ) }
|
|
32
32
|
|
|
33
33
|
let applyInstruction robot instruction =
|
|
34
34
|
match instruction with
|
|
@@ -37,4 +37,4 @@ let applyInstruction robot instruction =
|
|
|
37
37
|
| 'A' -> advance robot
|
|
38
38
|
| _ -> failwith "Invalid instruction"
|
|
39
39
|
|
|
40
|
-
let
|
|
40
|
+
let instructions instructions' robot = Seq.fold applyInstruction robot instructions'
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module RobotSimulator
|
|
2
2
|
|
|
3
|
-
type
|
|
4
|
-
type
|
|
3
|
+
type Direction = North | East | South | West
|
|
4
|
+
type Position = int * int
|
|
5
5
|
|
|
6
|
-
type Robot = {
|
|
6
|
+
type Robot = { direction: Direction; position: Position }
|
|
7
7
|
|
|
8
|
-
let
|
|
8
|
+
let create direction position = failwith "You need to implement this function."
|
|
9
9
|
|
|
10
10
|
let turnLeft robot = failwith "You need to implement this function."
|
|
11
11
|
|
|
@@ -13,4 +13,4 @@ let turnRight robot = failwith "You need to implement this function."
|
|
|
13
13
|
|
|
14
14
|
let advance robot = failwith "You need to implement this function."
|
|
15
15
|
|
|
16
|
-
let
|
|
16
|
+
let instructions instructions' robot = failwith "You need to implement this function."
|
|
@@ -8,140 +8,122 @@ open Xunit
|
|
|
8
8
|
open RobotSimulator
|
|
9
9
|
|
|
10
10
|
[<Fact>]
|
|
11
|
-
let ``
|
|
12
|
-
let robot =
|
|
13
|
-
let expected =
|
|
11
|
+
let ``Robots are created with a position and direction`` () =
|
|
12
|
+
let robot = create North (0, 0)
|
|
13
|
+
let expected = create North (0, 0)
|
|
14
14
|
robot |> should equal expected
|
|
15
15
|
|
|
16
16
|
[<Fact(Skip = "Remove to run test")>]
|
|
17
|
-
let ``
|
|
18
|
-
let robot =
|
|
19
|
-
let expected =
|
|
17
|
+
let ``Negative positions are allowed`` () =
|
|
18
|
+
let robot = create South (-1, -1)
|
|
19
|
+
let expected = create South (-1, -1)
|
|
20
20
|
robot |> should equal expected
|
|
21
21
|
|
|
22
22
|
[<Fact(Skip = "Remove to run test")>]
|
|
23
|
-
let ``turnRight
|
|
24
|
-
let robot =
|
|
25
|
-
let
|
|
26
|
-
|
|
27
|
-
actual.coordinate |> should equal expected
|
|
23
|
+
let ``turnRight does not change the position`` () =
|
|
24
|
+
let robot = create North (0, 0)
|
|
25
|
+
let sut = turnRight robot
|
|
26
|
+
sut.position |> should equal (0, 0)
|
|
28
27
|
|
|
29
28
|
[<Fact(Skip = "Remove to run test")>]
|
|
30
|
-
let ``turnRight
|
|
31
|
-
let robot =
|
|
32
|
-
let
|
|
33
|
-
|
|
34
|
-
actual.bearing |> should equal expected
|
|
29
|
+
let ``turnRight changes the direction from north to east`` () =
|
|
30
|
+
let robot = create North (0, 0)
|
|
31
|
+
let sut = turnRight robot
|
|
32
|
+
sut.direction |> should equal East
|
|
35
33
|
|
|
36
34
|
[<Fact(Skip = "Remove to run test")>]
|
|
37
|
-
let ``turnRight
|
|
38
|
-
let robot =
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
actual.bearing |> should equal expected
|
|
35
|
+
let ``turnRight changes the direction from east to south`` () =
|
|
36
|
+
let robot = create East (0, 0)
|
|
37
|
+
let sut = turnRight robot
|
|
38
|
+
sut.direction |> should equal South
|
|
42
39
|
|
|
43
40
|
[<Fact(Skip = "Remove to run test")>]
|
|
44
|
-
let ``turnRight
|
|
45
|
-
let robot =
|
|
46
|
-
let
|
|
47
|
-
|
|
48
|
-
actual.bearing |> should equal expected
|
|
41
|
+
let ``turnRight changes the direction from south to west`` () =
|
|
42
|
+
let robot = create South (0, 0)
|
|
43
|
+
let sut = turnRight robot
|
|
44
|
+
sut.direction |> should equal West
|
|
49
45
|
|
|
50
46
|
[<Fact(Skip = "Remove to run test")>]
|
|
51
|
-
let ``turnRight
|
|
52
|
-
let robot =
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
actual.bearing |> should equal expected
|
|
47
|
+
let ``turnRight changes the direction from west to north`` () =
|
|
48
|
+
let robot = create West (0, 0)
|
|
49
|
+
let sut = turnRight robot
|
|
50
|
+
sut.direction |> should equal North
|
|
56
51
|
|
|
57
52
|
[<Fact(Skip = "Remove to run test")>]
|
|
58
|
-
let ``turnLeft
|
|
59
|
-
let robot =
|
|
60
|
-
let
|
|
61
|
-
|
|
62
|
-
actual.coordinate |> should equal expected
|
|
53
|
+
let ``turnLeft does not change the position`` () =
|
|
54
|
+
let robot = create North (0, 0)
|
|
55
|
+
let sut = turnLeft robot
|
|
56
|
+
sut.position |> should equal (0, 0)
|
|
63
57
|
|
|
64
58
|
[<Fact(Skip = "Remove to run test")>]
|
|
65
|
-
let ``turnLeft
|
|
66
|
-
let robot =
|
|
67
|
-
let
|
|
68
|
-
|
|
69
|
-
actual.bearing |> should equal expected
|
|
59
|
+
let ``turnLeft changes the direction from north to west`` () =
|
|
60
|
+
let robot = create North (0, 0)
|
|
61
|
+
let sut = turnLeft robot
|
|
62
|
+
sut.direction |> should equal West
|
|
70
63
|
|
|
71
64
|
[<Fact(Skip = "Remove to run test")>]
|
|
72
|
-
let ``turnLeft
|
|
73
|
-
let robot =
|
|
74
|
-
let
|
|
75
|
-
|
|
76
|
-
actual.bearing |> should equal expected
|
|
65
|
+
let ``turnLeft changes the direction from west to south`` () =
|
|
66
|
+
let robot = create West (0, 0)
|
|
67
|
+
let sut = turnLeft robot
|
|
68
|
+
sut.direction |> should equal South
|
|
77
69
|
|
|
78
70
|
[<Fact(Skip = "Remove to run test")>]
|
|
79
|
-
let ``turnLeft
|
|
80
|
-
let robot =
|
|
81
|
-
let
|
|
82
|
-
|
|
83
|
-
actual.bearing |> should equal expected
|
|
71
|
+
let ``turnLeft changes the direction from south to east`` () =
|
|
72
|
+
let robot = create South (0, 0)
|
|
73
|
+
let sut = turnLeft robot
|
|
74
|
+
sut.direction |> should equal East
|
|
84
75
|
|
|
85
76
|
[<Fact(Skip = "Remove to run test")>]
|
|
86
|
-
let ``turnLeft
|
|
87
|
-
let robot =
|
|
88
|
-
let
|
|
89
|
-
|
|
90
|
-
actual.bearing |> should equal expected
|
|
77
|
+
let ``turnLeft changes the direction from east to north`` () =
|
|
78
|
+
let robot = create East (0, 0)
|
|
79
|
+
let sut = turnLeft robot
|
|
80
|
+
sut.direction |> should equal North
|
|
91
81
|
|
|
92
82
|
[<Fact(Skip = "Remove to run test")>]
|
|
93
|
-
let ``advance
|
|
94
|
-
let robot =
|
|
95
|
-
let
|
|
96
|
-
|
|
97
|
-
actual.bearing |> should equal expected
|
|
83
|
+
let ``advance does not change the direction`` () =
|
|
84
|
+
let robot = create North (0, 0)
|
|
85
|
+
let sut = advance robot
|
|
86
|
+
sut.direction |> should equal North
|
|
98
87
|
|
|
99
88
|
[<Fact(Skip = "Remove to run test")>]
|
|
100
|
-
let ``advance
|
|
101
|
-
let robot =
|
|
102
|
-
let
|
|
103
|
-
|
|
104
|
-
actual.coordinate |> should equal expected
|
|
89
|
+
let ``advance increases the y coordinate one when facing north`` () =
|
|
90
|
+
let robot = create North (0, 0)
|
|
91
|
+
let sut = advance robot
|
|
92
|
+
sut.position |> should equal (0, 1)
|
|
105
93
|
|
|
106
94
|
[<Fact(Skip = "Remove to run test")>]
|
|
107
|
-
let ``advance
|
|
108
|
-
let robot =
|
|
109
|
-
let
|
|
110
|
-
|
|
111
|
-
actual.coordinate |> should equal expected
|
|
95
|
+
let ``advance decreases the y coordinate by one when facing south`` () =
|
|
96
|
+
let robot = create South (0, 0)
|
|
97
|
+
let sut = advance robot
|
|
98
|
+
sut.position |> should equal (0, -1)
|
|
112
99
|
|
|
113
100
|
[<Fact(Skip = "Remove to run test")>]
|
|
114
|
-
let ``advance
|
|
115
|
-
let robot =
|
|
116
|
-
let
|
|
117
|
-
|
|
118
|
-
actual.coordinate |> should equal expected
|
|
101
|
+
let ``advance increases the x coordinate by one when facing east`` () =
|
|
102
|
+
let robot = create East (0, 0)
|
|
103
|
+
let sut = advance robot
|
|
104
|
+
sut.position |> should equal (1, 0)
|
|
119
105
|
|
|
120
106
|
[<Fact(Skip = "Remove to run test")>]
|
|
121
|
-
let ``advance
|
|
122
|
-
let robot =
|
|
123
|
-
let
|
|
124
|
-
|
|
125
|
-
actual.coordinate |> should equal expected
|
|
107
|
+
let ``advance decreases the x coordinate by one when facing west`` () =
|
|
108
|
+
let robot = create West (0, 0)
|
|
109
|
+
let sut = advance robot
|
|
110
|
+
sut.position |> should equal (-1, 0)
|
|
126
111
|
|
|
127
112
|
[<Fact(Skip = "Remove to run test")>]
|
|
128
|
-
let ``
|
|
129
|
-
let robot =
|
|
130
|
-
let
|
|
131
|
-
|
|
132
|
-
actual |> should equal expected
|
|
113
|
+
let ``Instructions to move west and north`` () =
|
|
114
|
+
let robot = create North (0, 0)
|
|
115
|
+
let expected = create West (-4, 1)
|
|
116
|
+
instructions "LAAARALA" robot |> should equal expected
|
|
133
117
|
|
|
134
118
|
[<Fact(Skip = "Remove to run test")>]
|
|
135
|
-
let ``
|
|
136
|
-
let robot =
|
|
137
|
-
let
|
|
138
|
-
|
|
139
|
-
actual |> should equal expected
|
|
119
|
+
let ``Instructions to move west and south`` () =
|
|
120
|
+
let robot = create East (2, -7)
|
|
121
|
+
let expected = create South (-3, -8)
|
|
122
|
+
instructions "RRAAAAALA" robot |> should equal expected
|
|
140
123
|
|
|
141
124
|
[<Fact(Skip = "Remove to run test")>]
|
|
142
|
-
let ``
|
|
143
|
-
let robot =
|
|
144
|
-
let
|
|
145
|
-
|
|
146
|
-
actual |> should equal expected
|
|
125
|
+
let ``Instructions to move east and north`` () =
|
|
126
|
+
let robot = create South (8, 4)
|
|
127
|
+
let expected = create North (11, 5)
|
|
128
|
+
instructions "LAAARRRALLLL" robot |> should equal expected
|
|
147
129
|
|
|
@@ -9,6 +9,23 @@ open Newtonsoft.Json
|
|
|
9
9
|
open Newtonsoft.Json.Linq
|
|
10
10
|
open Options
|
|
11
11
|
|
|
12
|
+
type CanonicalDataCase =
|
|
13
|
+
{ Input: Map<string, obj>
|
|
14
|
+
Expected: obj
|
|
15
|
+
Property: string
|
|
16
|
+
Properties: Map<string, obj>
|
|
17
|
+
Description: string
|
|
18
|
+
DescriptionPath: string list }
|
|
19
|
+
|
|
20
|
+
type CanonicalData =
|
|
21
|
+
{ Exercise: string
|
|
22
|
+
Version: string
|
|
23
|
+
Cases: CanonicalDataCase list }
|
|
24
|
+
|
|
25
|
+
type CanonicalDataFormat =
|
|
26
|
+
| Old
|
|
27
|
+
| New
|
|
28
|
+
|
|
12
29
|
let [<Literal>] private ProblemSpecificationsGitUrl = "https://github.com/exercism/problem-specifications.git";
|
|
13
30
|
let [<Literal>] private ProblemSpecificationsBranch = "master";
|
|
14
31
|
let [<Literal>] private ProblemSpecificationsRemote = "origin";
|
|
@@ -46,7 +63,7 @@ let private downloadData options =
|
|
|
46
63
|
type CanonicalDataConverter() =
|
|
47
64
|
inherit JsonConverter()
|
|
48
65
|
|
|
49
|
-
let
|
|
66
|
+
let jTokenToMap (jToken: JToken) =
|
|
50
67
|
jToken.ToObject<IDictionary<string, obj>>()
|
|
51
68
|
|> Dict.toMap
|
|
52
69
|
|
|
@@ -60,8 +77,32 @@ type CanonicalDataConverter() =
|
|
|
60
77
|
|> Json.parentsAndSelf
|
|
61
78
|
|> List.choose descriptionFromJToken
|
|
62
79
|
|
|
80
|
+
let createInputFromJTokenInNewFormat (properties: Map<string, obj>) =
|
|
81
|
+
(properties.["input"] :?> JObject)
|
|
82
|
+
|> jTokenToMap
|
|
83
|
+
|
|
84
|
+
let createInputFromJTokenInOldFormat (properties: Map<string, obj>) =
|
|
85
|
+
properties
|
|
86
|
+
|> Map.filter (fun key _ -> List.contains key ["expected"; "property"; "description"; "comments"] |> not)
|
|
87
|
+
|
|
88
|
+
let detectCanonicalDataFormatFromJToken (properties: Map<string, obj>) =
|
|
89
|
+
match properties.ContainsKey "input" && properties.["input"] :? JObject with
|
|
90
|
+
| true -> New
|
|
91
|
+
| false -> Old
|
|
92
|
+
|
|
93
|
+
let createInputFromJToken (properties: Map<string, obj>) =
|
|
94
|
+
match detectCanonicalDataFormatFromJToken properties with
|
|
95
|
+
| Old -> createInputFromJTokenInOldFormat properties
|
|
96
|
+
| New -> createInputFromJTokenInNewFormat properties
|
|
97
|
+
|
|
63
98
|
let createCanonicalDataCaseFromJToken (jToken: JToken) =
|
|
64
|
-
|
|
99
|
+
let properties = jTokenToMap jToken
|
|
100
|
+
|
|
101
|
+
{ Input = createInputFromJToken properties
|
|
102
|
+
Expected = properties.["expected"]
|
|
103
|
+
Property = string properties.["property"]
|
|
104
|
+
Properties = properties
|
|
105
|
+
Description = string properties.["description"]
|
|
65
106
|
DescriptionPath = createDescriptionPathFromJToken jToken }
|
|
66
107
|
|
|
67
108
|
let createCanonicalDataCasesFromJToken (jToken: JToken) =
|
|
@@ -83,7 +124,8 @@ type CanonicalDataConverter() =
|
|
|
83
124
|
override __.CanConvert(objectType: Type) = objectType = typeof<CanonicalData>
|
|
84
125
|
|
|
85
126
|
let private convertCanonicalData canonicalDataContents =
|
|
86
|
-
|
|
127
|
+
let converter = CanonicalDataConverter()
|
|
128
|
+
JsonConvert.DeserializeObject<CanonicalData>(canonicalDataContents, converter)
|
|
87
129
|
|
|
88
130
|
let private canonicalDataFile options exercise =
|
|
89
131
|
Path.Combine(options.CanonicalDataDirectory, "exercises", exercise, "canonical-data.json")
|
|
@@ -98,4 +140,8 @@ let hasCanonicalData options exercise =
|
|
|
98
140
|
|
|
99
141
|
let parseCanonicalData options =
|
|
100
142
|
downloadData options
|
|
101
|
-
|
|
143
|
+
|
|
144
|
+
fun exercise ->
|
|
145
|
+
exercise
|
|
146
|
+
|> readCanonicalData options
|
|
147
|
+
|> convertCanonicalData
|
|
@@ -5,19 +5,6 @@ open System
|
|
|
5
5
|
open Serilog
|
|
6
6
|
open Newtonsoft.Json.Linq
|
|
7
7
|
|
|
8
|
-
type CanonicalDataCase =
|
|
9
|
-
{ Properties: Map<string, obj>
|
|
10
|
-
DescriptionPath: string list } with
|
|
11
|
-
member this.Description = string this.Properties.["description"]
|
|
12
|
-
member this.Property = string this.Properties.["property"]
|
|
13
|
-
member this.Expected = this.Properties.["expected"]
|
|
14
|
-
member this.Input = this.Properties.["input"]
|
|
15
|
-
|
|
16
|
-
type CanonicalData =
|
|
17
|
-
{ Exercise: string
|
|
18
|
-
Version: string
|
|
19
|
-
Cases: CanonicalDataCase list }
|
|
20
|
-
|
|
21
8
|
type TestMethod =
|
|
22
9
|
{ Skip: bool
|
|
23
10
|
Name: string
|
|
@@ -94,6 +81,10 @@ module String =
|
|
|
94
81
|
| "" -> str
|
|
95
82
|
| _ -> sprintf "%c%s" (Char.ToUpper(str.[0])) str.[1..]
|
|
96
83
|
|
|
84
|
+
let lowerCaseFirst (str: string) =
|
|
85
|
+
match str with
|
|
86
|
+
| "" -> str
|
|
87
|
+
| _ -> sprintf "%c%s" (Char.ToLower(str.[0])) str.[1..]
|
|
97
88
|
|
|
98
89
|
module Json =
|
|
99
90
|
let rec parentsAndSelf (currentToken: JToken) =
|
|
@@ -19,8 +19,9 @@ type GeneratorExercise() =
|
|
|
19
19
|
// Allow changes in canonical data
|
|
20
20
|
abstract member MapCanonicalData : CanonicalData -> CanonicalData
|
|
21
21
|
abstract member MapCanonicalDataCase : CanonicalDataCase -> CanonicalDataCase
|
|
22
|
-
abstract member
|
|
23
|
-
abstract member
|
|
22
|
+
abstract member MapCanonicalDataCaseInput : CanonicalDataCase * Map<string, obj> -> Map<string, obj>
|
|
23
|
+
abstract member MapCanonicalDataCaseInputProperty : CanonicalDataCase * string * obj -> obj
|
|
24
|
+
abstract member MapCanonicalDataCaseExpected : CanonicalDataCase * string * obj -> obj
|
|
24
25
|
|
|
25
26
|
// Convert canonical data to representation used when rendering
|
|
26
27
|
abstract member ToTestFile : CanonicalData -> TestFile
|
|
@@ -91,13 +92,16 @@ type GeneratorExercise() =
|
|
|
91
92
|
|
|
92
93
|
default this.MapCanonicalDataCase canonicalDataCase =
|
|
93
94
|
{ canonicalDataCase with
|
|
94
|
-
|
|
95
|
+
Input = this.MapCanonicalDataCaseInput (canonicalDataCase, canonicalDataCase.Input)
|
|
96
|
+
Expected = this.MapCanonicalDataCaseExpected (canonicalDataCase, "expected", canonicalDataCase.Expected) }
|
|
95
97
|
|
|
96
|
-
default this.
|
|
98
|
+
default this.MapCanonicalDataCaseInput (canonicalDataCase, properties) =
|
|
97
99
|
properties
|
|
98
|
-
|> Map.map (fun key value -> this.
|
|
100
|
+
|> Map.map (fun key value -> this.MapCanonicalDataCaseInputProperty (canonicalDataCase, key, value))
|
|
99
101
|
|
|
100
|
-
default __.
|
|
102
|
+
default __.MapCanonicalDataCaseInputProperty (_, _, value) = value
|
|
103
|
+
|
|
104
|
+
default __.MapCanonicalDataCaseExpected (_, _, value) = value
|
|
101
105
|
|
|
102
106
|
// Convert canonical data to representation used when rendering
|
|
103
107
|
|
|
@@ -122,7 +126,7 @@ type GeneratorExercise() =
|
|
|
122
126
|
Assert = this.RenderAssert canonicalDataCase }
|
|
123
127
|
|
|
124
128
|
default this.ToTestMethodBodyAssert canonicalDataCase =
|
|
125
|
-
{ Sut = this.
|
|
129
|
+
{ Sut = this.RenderValueOrIdentifier (canonicalDataCase, "sut", canonicalDataCase.Expected)
|
|
126
130
|
Expected = this.RenderValueOrIdentifier (canonicalDataCase, "expected", canonicalDataCase.Expected) }
|
|
127
131
|
|
|
128
132
|
// Determine the templates to use when rendering
|
|
@@ -195,6 +199,7 @@ type GeneratorExercise() =
|
|
|
195
199
|
default this.RenderValueWithoutIdentifier (canonicalDataCase, key, value) =
|
|
196
200
|
match key with
|
|
197
201
|
| "expected" -> this.RenderExpected (canonicalDataCase, key, value)
|
|
202
|
+
| "sut" -> this.RenderSut canonicalDataCase
|
|
198
203
|
| _ -> this.RenderInput (canonicalDataCase, key, value)
|
|
199
204
|
|
|
200
205
|
default this.RenderValueWithIdentifier (canonicalDataCase, key, value) =
|
|
@@ -220,10 +225,22 @@ type GeneratorExercise() =
|
|
|
220
225
|
default this.RenderInput (canonicalDataCase, key, value) = this.RenderValue (canonicalDataCase, key, value)
|
|
221
226
|
|
|
222
227
|
default this.RenderArrange canonicalDataCase =
|
|
223
|
-
let
|
|
224
|
-
|
|
228
|
+
let renderExpected prop =
|
|
229
|
+
this.RenderValueWithIdentifier (canonicalDataCase, prop, canonicalDataCase.Expected) |> Some
|
|
230
|
+
|
|
231
|
+
let renderSut prop =
|
|
232
|
+
this.RenderValueWithIdentifier (canonicalDataCase, prop, canonicalDataCase.Expected) |> Some
|
|
233
|
+
|
|
234
|
+
let renderInput prop =
|
|
235
|
+
match Map.tryFind prop canonicalDataCase.Input with
|
|
225
236
|
| None -> None
|
|
226
|
-
| Some value -> Some (this.RenderValueWithIdentifier (canonicalDataCase,
|
|
237
|
+
| Some value -> Some (this.RenderValueWithIdentifier (canonicalDataCase, prop, value))
|
|
238
|
+
|
|
239
|
+
let renderArrangeProperty prop: string option =
|
|
240
|
+
match prop with
|
|
241
|
+
| "expected" -> renderExpected prop
|
|
242
|
+
| "sut" -> renderSut prop
|
|
243
|
+
| _ -> renderInput prop
|
|
227
244
|
|
|
228
245
|
canonicalDataCase
|
|
229
246
|
|> this.PropertiesWithIdentifier
|
|
@@ -238,12 +255,12 @@ type GeneratorExercise() =
|
|
|
238
255
|
|
|
239
256
|
default this.RenderSut canonicalDataCase =
|
|
240
257
|
let parameters = this.RenderSutParameters canonicalDataCase
|
|
241
|
-
let
|
|
242
|
-
|
|
258
|
+
let prop = this.RenderSutProperty canonicalDataCase
|
|
259
|
+
prop :: parameters |> String.concat " "
|
|
243
260
|
|
|
244
261
|
default this.RenderSutParameters canonicalDataCase =
|
|
245
262
|
let sutParameterProperties = this.PropertiesUsedAsSutParameter canonicalDataCase
|
|
246
|
-
let renderSutParameter key = this.RenderSutParameter (canonicalDataCase, key, Map.find key canonicalDataCase.
|
|
263
|
+
let renderSutParameter key = this.RenderSutParameter (canonicalDataCase, key, Map.find key canonicalDataCase.Input)
|
|
247
264
|
|
|
248
265
|
sutParameterProperties
|
|
249
266
|
|> List.map renderSutParameter
|
|
@@ -257,10 +274,9 @@ type GeneratorExercise() =
|
|
|
257
274
|
List.append (this.PropertiesUsedAsSutParameter canonicalDataCase) ["expected"]
|
|
258
275
|
|
|
259
276
|
default __.PropertiesUsedAsSutParameter canonicalDataCase =
|
|
260
|
-
canonicalDataCase.
|
|
277
|
+
canonicalDataCase.Input
|
|
261
278
|
|> Map.toList
|
|
262
279
|
|> List.map fst
|
|
263
|
-
|> List.except ["expected"; "property"; "description"; "comments"]
|
|
264
280
|
|
|
265
281
|
// Utility methods to customize rendered output
|
|
266
282
|
|