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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/bowling/canonical-data.json +95 -39
  4. data/problem-specifications/exercises/gigasecond/canonical-data.json +17 -7
  5. data/problem-specifications/exercises/pangram/canonical-data.json +32 -12
  6. data/problem-specifications/exercises/say/canonical-data.json +47 -17
  7. data/problem-specifications/exercises/sum-of-multiples/canonical-data.json +54 -28
  8. data/problem-specifications/exercises/triangle/canonical-data.json +52 -18
  9. data/problem-specifications/exercises/two-bucket/canonical-data.json +38 -26
  10. data/problem-specifications/exercises/two-fer/canonical-data.json +14 -8
  11. data/problem-specifications/exercises/word-count/canonical-data.json +35 -13
  12. data/problem-specifications/exercises/wordy/canonical-data.json +50 -18
  13. data/tracks/bash/exercises/leap/.meta/version +1 -0
  14. data/tracks/bash/exercises/leap/example.sh +9 -9
  15. data/tracks/bash/exercises/leap/leap_test.sh +17 -33
  16. data/tracks/ceylon/exercises/anagram/source/anagram/AnagramTest.ceylon +1 -1
  17. data/tracks/ceylon/exercises/bracket-push/source/bracketpush/BracketsTest.ceylon +1 -1
  18. data/tracks/ceylon/exercises/rna-transcription/source/rnatranscription/RNATest.ceylon +2 -1
  19. data/tracks/fsharp/build.cake +2 -7
  20. data/tracks/fsharp/exercises/acronym/AcronymTest.fs +1 -1
  21. data/tracks/fsharp/exercises/all-your-base/AllYourBase.fs +1 -1
  22. data/tracks/fsharp/exercises/all-your-base/AllYourBaseTest.fs +43 -43
  23. data/tracks/fsharp/exercises/all-your-base/Example.fs +5 -5
  24. data/tracks/fsharp/exercises/allergies/AllergiesTest.fs +1 -1
  25. data/tracks/fsharp/exercises/alphametics/AlphameticsTest.fs +19 -1
  26. data/tracks/fsharp/exercises/alphametics/Example.fs +53 -34
  27. data/tracks/fsharp/exercises/anagram/AnagramTest.fs +1 -1
  28. data/tracks/fsharp/exercises/atbash-cipher/AtbashCipherTest.fs +1 -1
  29. data/tracks/fsharp/exercises/beer-song/BeerSongTest.fs +1 -1
  30. data/tracks/fsharp/exercises/binary-search/BinarySearchTest.fs +1 -1
  31. data/tracks/fsharp/exercises/bob/BobTest.fs +1 -1
  32. data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +1 -1
  33. data/tracks/fsharp/exercises/bracket-push/BracketPushTest.fs +1 -1
  34. data/tracks/fsharp/exercises/change/ChangeTest.fs +1 -1
  35. data/tracks/fsharp/exercises/collatz-conjecture/CollatzConjectureTest.fs +1 -1
  36. data/tracks/fsharp/exercises/connect/ConnectTest.fs +1 -1
  37. data/tracks/fsharp/exercises/crypto-square/CryptoSquareTest.fs +1 -1
  38. data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquaresTest.fs +1 -1
  39. data/tracks/fsharp/exercises/dominoes/DominoesTest.fs +25 -25
  40. data/tracks/fsharp/exercises/etl/EtlTest.fs +8 -8
  41. data/tracks/fsharp/exercises/isbn-verifier/IsbnVerifierTest.fs +5 -1
  42. data/tracks/fsharp/exercises/luhn/LuhnTest.fs +1 -1
  43. data/tracks/fsharp/exercises/meetup/Example.fs +11 -11
  44. data/tracks/fsharp/exercises/meetup/Meetup.fs +2 -2
  45. data/tracks/fsharp/exercises/meetup/MeetupTest.fs +96 -96
  46. data/tracks/fsharp/exercises/robot-simulator/Example.fs +21 -21
  47. data/tracks/fsharp/exercises/robot-simulator/RobotSimulator.fs +5 -5
  48. data/tracks/fsharp/exercises/robot-simulator/RobotSimulatorTest.fs +78 -96
  49. data/tracks/fsharp/generators/CanonicalData.fs +50 -4
  50. data/tracks/fsharp/generators/Common.fs +4 -13
  51. data/tracks/fsharp/generators/Exercise.fs +31 -15
  52. data/tracks/fsharp/generators/Generators.fs +76 -111
  53. data/tracks/haskell/exercises/alphametics/package.yaml +1 -1
  54. data/tracks/haskell/exercises/alphametics/test/Tests.hs +5 -0
  55. data/tracks/haskell/exercises/bowling/package.yaml +1 -1
  56. data/tracks/haskell/exercises/pangram/package.yaml +1 -1
  57. data/tracks/haskell/exercises/say/package.yaml +1 -1
  58. data/tracks/haskell/exercises/sum-of-multiples/package.yaml +1 -1
  59. data/tracks/haskell/exercises/word-count/package.yaml +1 -1
  60. data/tracks/haskell/exercises/wordy/package.yaml +1 -1
  61. data/tracks/java/exercises/nucleotide-count/.meta/hints.md +58 -0
  62. data/tracks/java/exercises/nucleotide-count/README.md +62 -0
  63. metadata +4 -2
@@ -1,34 +1,34 @@
1
1
  module RobotSimulator
2
2
 
3
- type Bearing = North | East | South | West
4
- type Coordinate = int * int
3
+ type Direction = North | East | South | West
4
+ type Position = int * int
5
5
 
6
- type Robot = { bearing: Bearing; coordinate: Coordinate }
6
+ type Robot = { direction: Direction; position: Position }
7
7
 
8
- let createRobot bearing coordinate = { bearing = bearing; coordinate = coordinate }
8
+ let create bearing position = { direction = bearing; position = position }
9
9
 
10
10
  let turnLeft robot =
11
- match robot.bearing with
12
- | North -> { robot with bearing = West }
13
- | East -> { robot with bearing = North }
14
- | South -> { robot with bearing = East }
15
- | West -> { robot with bearing = South }
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.bearing with
19
- | North -> { robot with bearing = East }
20
- | East -> { robot with bearing = South }
21
- | South -> { robot with bearing = West }
22
- | West -> { robot with bearing = North }
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.coordinate
25
+ let (x, y) = robot.position
26
26
 
27
- match robot.bearing with
28
- | North -> { robot with coordinate = (x , y + 1) }
29
- | East -> { robot with coordinate = (x + 1, y ) }
30
- | South -> { robot with coordinate = (x , y - 1) }
31
- | West -> { robot with coordinate = (x - 1, y ) }
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 simulate robot instructions = Seq.fold applyInstruction robot instructions
40
+ let instructions instructions' robot = Seq.fold applyInstruction robot instructions'
@@ -1,11 +1,11 @@
1
1
  module RobotSimulator
2
2
 
3
- type Bearing = North | East | South | West
4
- type Coordinate = int * int
3
+ type Direction = North | East | South | West
4
+ type Position = int * int
5
5
 
6
- type Robot = { bearing: Bearing; coordinate: Coordinate }
6
+ type Robot = { direction: Direction; position: Position }
7
7
 
8
- let createRobot bearing coordinate = failwith "You need to implement this function."
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 simulate robot instructions = failwith "You need to implement this function."
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 ``create - Robots are created with a position and direction`` () =
12
- let robot = createRobot North (0, 0)
13
- let expected = createRobot North (0, 0)
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 ``create - Negative positions are allowed`` () =
18
- let robot = createRobot South (-1, -1)
19
- let expected = createRobot South (-1, -1)
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 - Does not change the position`` () =
24
- let robot = createRobot North (0, 0)
25
- let actual = turnRight robot
26
- let expected = (0, 0)
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 - Changes the direction from north to east`` () =
31
- let robot = createRobot North (0, 0)
32
- let actual = turnRight robot
33
- let expected = East
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 - Changes the direction from east to south`` () =
38
- let robot = createRobot East (0, 0)
39
- let actual = turnRight robot
40
- let expected = South
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 - Changes the direction from south to west`` () =
45
- let robot = createRobot South (0, 0)
46
- let actual = turnRight robot
47
- let expected = West
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 - Changes the direction from west to north`` () =
52
- let robot = createRobot West (0, 0)
53
- let actual = turnRight robot
54
- let expected = North
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 - Does not change the position`` () =
59
- let robot = createRobot North (0, 0)
60
- let actual = turnLeft robot
61
- let expected = (0, 0)
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 - Changes the direction from north to west`` () =
66
- let robot = createRobot North (0, 0)
67
- let actual = turnLeft robot
68
- let expected = West
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 - Changes the direction from west to south`` () =
73
- let robot = createRobot West (0, 0)
74
- let actual = turnLeft robot
75
- let expected = South
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 - Changes the direction from south to east`` () =
80
- let robot = createRobot South (0, 0)
81
- let actual = turnLeft robot
82
- let expected = East
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 - Changes the direction from east to north`` () =
87
- let robot = createRobot East (0, 0)
88
- let actual = turnLeft robot
89
- let expected = North
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 - Does not change the direction`` () =
94
- let robot = createRobot North (0, 0)
95
- let actual = advance robot
96
- let expected = North
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 - Increases the y coordinate one when facing north`` () =
101
- let robot = createRobot North (0, 0)
102
- let actual = advance robot
103
- let expected = (0, 1)
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 - Decreases the y coordinate by one when facing south`` () =
108
- let robot = createRobot South (0, 0)
109
- let actual = advance robot
110
- let expected = (0, -1)
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 - Increases the x coordinate by one when facing east`` () =
115
- let robot = createRobot East (0, 0)
116
- let actual = advance robot
117
- let expected = (1, 0)
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 - Decreases the x coordinate by one when facing west`` () =
122
- let robot = createRobot West (0, 0)
123
- let actual = advance robot
124
- let expected = (-1, 0)
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 ``instructions - Instructions to move west and north`` () =
129
- let robot = createRobot North (0, 0)
130
- let actual = simulate robot "LAAARALA"
131
- let expected = createRobot West (-4, 1)
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 ``instructions - Instructions to move west and south`` () =
136
- let robot = createRobot East (2, -7)
137
- let actual = simulate robot "RRAAAAALA"
138
- let expected = createRobot South (-3, -8)
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 ``instructions - Instructions to move east and north`` () =
143
- let robot = createRobot South (8, 4)
144
- let actual = simulate robot "LAAARRRALLLL"
145
- let expected = createRobot North (11, 5)
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 createCanonicalDataCasePropertiesFromJToken (jToken: JToken) =
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
- { Properties = createCanonicalDataCasePropertiesFromJToken jToken
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
- JsonConvert.DeserializeObject<CanonicalData>(canonicalDataContents, CanonicalDataConverter())
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
- readCanonicalData options >> convertCanonicalData
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 MapCanonicalDataCaseProperties : CanonicalDataCase * Map<string, obj> -> Map<string, obj>
23
- abstract member MapCanonicalDataCaseProperty : CanonicalDataCase * string * obj -> obj
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
- Properties = this.MapCanonicalDataCaseProperties (canonicalDataCase, canonicalDataCase.Properties) }
95
+ Input = this.MapCanonicalDataCaseInput (canonicalDataCase, canonicalDataCase.Input)
96
+ Expected = this.MapCanonicalDataCaseExpected (canonicalDataCase, "expected", canonicalDataCase.Expected) }
95
97
 
96
- default this.MapCanonicalDataCaseProperties (canonicalDataCase, properties) =
98
+ default this.MapCanonicalDataCaseInput (canonicalDataCase, properties) =
97
99
  properties
98
- |> Map.map (fun key value -> this.MapCanonicalDataCaseProperty (canonicalDataCase, key, value))
100
+ |> Map.map (fun key value -> this.MapCanonicalDataCaseInputProperty (canonicalDataCase, key, value))
99
101
 
100
- default __.MapCanonicalDataCaseProperty (_, _, value) = value
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.RenderSut canonicalDataCase
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 renderArrangeProperty property: string option =
224
- match Map.tryFind property canonicalDataCase.Properties with
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, property, value))
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 property = this.RenderSutProperty canonicalDataCase
242
- property :: parameters |> String.concat " "
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.Properties)
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.Properties
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