Skip to content

Commit 9309133

Browse files
test: add coverage for untested List and Array module functions
Add 33 new tests covering functions in List and Array that had no test coverage: List: singleton, cons, findExactlyOne, skip, take, skipWhile, skipUntil, takeWhile, takeUntil, groupNeighboursBy, mapIf, catOptions, choice1s, choice2s, partitionChoices, equalsWith Array: nth, setAt, findExactlyOne, centralMovingAverageOfOption, catOptions, choice1s, choice2s, partitionChoices, equalsWith Total test count increases from ~710 to 743. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 7325575 commit 9309133

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

tests/FSharpx.Collections.Tests/ArrayTests.fs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,67 @@ module ArrayTests =
5151

5252
Expect.equal "expect arrays equal" expected
5353
<| Array.centralMovingAverage 3 data
54+
}
55+
56+
test "nth returns element at index" { Expect.equal "nth" 3 (Array.nth 2 [| 1; 2; 3; 4; 5 |]) }
57+
58+
test "setAt mutates element at index and returns array" {
59+
let a = [| 1; 2; 3 |]
60+
let result = Array.setAt 1 99 a
61+
Expect.equal "setAt value" 99 result.[1]
62+
Expect.isTrue "setAt same ref" (obj.ReferenceEquals(a, result))
63+
}
64+
65+
test "findExactlyOne returns the sole matching element" {
66+
Expect.equal "findExactlyOne" 3 (Array.findExactlyOne ((=) 3) [| 1; 2; 3; 4; 5 |])
67+
}
68+
69+
test "findExactlyOne throws when no element matches" {
70+
Expect.throws "findExactlyOne no match"
71+
<| fun () -> Array.findExactlyOne ((=) 99) [| 1; 2; 3 |] |> ignore
72+
}
73+
74+
test "centralMovingAverageOfOption handles None entries" {
75+
let a = [| Some 1.0; None; Some 3.0 |]
76+
let result = Array.centralMovingAverageOfOption 1 a
77+
Expect.equal "centralMovingAverageOfOption" [| None; None; None |] result
78+
}
79+
80+
test "centralMovingAverageOfOption all Some" {
81+
let a = [| Some 1.0; Some 2.0; Some 3.0 |]
82+
let result = Array.centralMovingAverageOfOption 1 a
83+
Expect.equal "centralMovingAverageOfOption all Some" [| Some 1.5; Some 2.0; Some 2.5 |] result
84+
}
85+
86+
test "catOptions extracts Some values from array of options" {
87+
Expect.equal "catOptions" [| 1; 3 |] (Array.catOptions [| Some 1; None; Some 3; None |])
88+
}
89+
90+
test "choice1s extracts Choice1Of2 values" {
91+
let xs = [| Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" |]
92+
Expect.equal "choice1s" [| 1; 2 |] (Array.choice1s xs)
93+
}
94+
95+
test "choice2s extracts Choice2Of2 values" {
96+
let xs = [| Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" |]
97+
Expect.equal "choice2s" [| "a"; "b" |] (Array.choice2s xs)
98+
}
99+
100+
test "partitionChoices separates Choice1Of2 and Choice2Of2" {
101+
let xs = [| Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" |]
102+
let c1s, c2s = Array.partitionChoices xs
103+
Expect.equal "partitionChoices c1s" [| 1; 2 |] c1s
104+
Expect.equal "partitionChoices c2s" [| "a"; "b" |] c2s
105+
}
106+
107+
test "equalsWith returns true for element-wise equal arrays" {
108+
Expect.isTrue "equalsWith true" (Array.equalsWith (=) [| 1; 2; 3 |] [| 1; 2; 3 |])
109+
}
110+
111+
test "equalsWith returns false for unequal arrays" {
112+
Expect.isFalse "equalsWith false" (Array.equalsWith (=) [| 1; 2; 3 |] [| 1; 2; 4 |])
113+
}
114+
115+
test "equalsWith returns false for arrays of different length" {
116+
Expect.isFalse "equalsWith length" (Array.equalsWith (=) [| 1; 2 |] [| 1; 2; 3 |])
54117
} ]

tests/FSharpx.Collections.Tests/ListExtensionsTest.fs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,91 @@ module ListExtensionsTests =
8080
let a = [ [ 1; 2; 3 ]; [ 4; 5; 6 ] ]
8181
let expected = [ [ 1; 4 ]; [ 2; 5 ]; [ 3; 6 ] ]
8282
Expect.equal "transpose" expected (a |> List.transpose)
83+
}
84+
85+
test "singleton creates a one-element list" { Expect.equal "singleton" [ 42 ] (List.singleton 42) }
86+
87+
test "cons prepends an element" { Expect.equal "cons" [ 1; 2; 3 ] (List.cons 1 [ 2; 3 ]) }
88+
89+
test "findExactlyOne returns the sole matching element" {
90+
Expect.equal "findExactlyOne" 3 (List.findExactlyOne ((=) 3) [ 1; 2; 3; 4; 5 ])
91+
}
92+
93+
test "findExactlyOne throws when no element matches" {
94+
Expect.throws "findExactlyOne no match" (fun () -> List.findExactlyOne ((=) 99) [ 1; 2; 3 ] |> ignore)
95+
}
96+
97+
test "findExactlyOne throws when multiple elements match" {
98+
Expect.throws "findExactlyOne multiple" (fun () -> List.findExactlyOne ((=) 1) [ 1; 1; 2 ] |> ignore)
99+
}
100+
101+
test "skip removes first n elements" { Expect.equal "skip" [ 3; 4; 5 ] (List.skip 2 [ 1; 2; 3; 4; 5 ]) }
102+
103+
test "skip 0 returns whole list" { Expect.equal "skip 0" [ 1; 2; 3 ] (List.skip 0 [ 1; 2; 3 ]) }
104+
105+
test "take returns first n elements" { Expect.equal "take" [ 1; 2 ] (List.take 2 [ 1; 2; 3; 4; 5 ]) }
106+
107+
test "take 0 returns empty list" { Expect.equal "take 0" [] (List.take 0 [ 1; 2; 3 ]) }
108+
109+
test "skipWhile skips leading elements satisfying predicate" {
110+
Expect.equal "skipWhile" [ 3; 4; 5 ] (List.skipWhile (fun x -> x < 3) [ 1; 2; 3; 4; 5 ])
111+
}
112+
113+
test "skipUntil skips until predicate is satisfied" {
114+
Expect.equal "skipUntil" [ 3; 4; 5 ] (List.skipUntil (fun x -> x = 3) [ 1; 2; 3; 4; 5 ])
115+
}
116+
117+
test "takeWhile takes leading elements satisfying predicate" {
118+
Expect.equal "takeWhile" [ 1; 2 ] (List.takeWhile (fun x -> x < 3) [ 1; 2; 3; 4; 5 ])
119+
}
120+
121+
test "takeUntil takes until predicate is satisfied" {
122+
Expect.equal "takeUntil" [ 1; 2 ] (List.takeUntil (fun x -> x = 3) [ 1; 2; 3; 4; 5 ])
123+
}
124+
125+
test "groupNeighboursBy groups consecutive equal keys" {
126+
let result = List.groupNeighboursBy id [ 1; 1; 2; 2; 1 ]
127+
Expect.equal "groupNeighboursBy" [ (1, [ 1; 1 ]); (2, [ 2; 2 ]); (1, [ 1 ]) ] result
128+
}
129+
130+
test "groupNeighboursBy on empty list" { Expect.equal "groupNeighboursBy empty" [] (List.groupNeighboursBy id []) }
131+
132+
test "mapIf maps elements matching predicate, leaves others unchanged" {
133+
let result = List.mapIf (fun x -> x % 2 = 0) ((*) 10) [ 1; 2; 3; 4; 5 ]
134+
Expect.equal "mapIf" [ 1; 20; 3; 40; 5 ] result
135+
}
136+
137+
test "catOptions extracts Some values from list of options" {
138+
Expect.equal "catOptions" [ 1; 3 ] (List.catOptions [ Some 1; None; Some 3; None ])
139+
}
140+
141+
test "catOptions on all-None list" { Expect.equal "catOptions all-None" [] (List.catOptions [ None; None ]) }
142+
143+
test "choice1s extracts Choice1Of2 values" {
144+
let xs = [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ]
145+
Expect.equal "choice1s" [ 1; 2 ] (List.choice1s xs)
146+
}
147+
148+
test "choice2s extracts Choice2Of2 values" {
149+
let xs = [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ]
150+
Expect.equal "choice2s" [ "a"; "b" ] (List.choice2s xs)
151+
}
152+
153+
test "partitionChoices separates Choice1Of2 and Choice2Of2" {
154+
let xs = [ Choice1Of2 1; Choice2Of2 "a"; Choice1Of2 2; Choice2Of2 "b" ]
155+
let c1s, c2s = List.partitionChoices xs
156+
Expect.equal "partitionChoices c1s" [ 1; 2 ] c1s
157+
Expect.equal "partitionChoices c2s" [ "a"; "b" ] c2s
158+
}
159+
160+
test "equalsWith returns true for element-wise equal lists" {
161+
Expect.isTrue "equalsWith true" (List.equalsWith (=) [ 1; 2; 3 ] [ 1; 2; 3 ])
162+
}
163+
164+
test "equalsWith returns false for unequal lists" { Expect.isFalse "equalsWith false" (List.equalsWith (=) [ 1; 2; 3 ] [ 1; 2; 4 ]) }
165+
166+
test "equalsWith returns false for lists of different length" {
167+
Expect.isFalse "equalsWith length" (List.equalsWith (=) [ 1; 2 ] [ 1; 2; 3 ])
83168
} ]
84169

85170
[<Tests>]

0 commit comments

Comments
 (0)