@@ -177,7 +177,30 @@ module Extensions =
177177 Expect.equal xs.Second 6 " Expected Second to be changed to the new value"
178178
179179 //---- xs.Third ----
180- // Similar tests can be written for Third
180+ testCase " Third getter raises exception on Array with less than 3 items" <| fun _ ->
181+ let xs = [| 1 ; 2 |]
182+ let testCode = fun () -> xs.Third |> ignore
183+ Expect.throws testCode " Expected an IndexOutOfRangeException"
184+
185+ testCase " Third setter raises exception on Array with less than 3 items" <| fun _ ->
186+ let xs = [| 1 ; 2 |]
187+ let testCode = fun () -> xs.Third <- 1
188+ Expect.throws testCode " Expected an IndexOutOfRangeException"
189+
190+ testCase " Third getter returns third item on Array with 3 or more items" <| fun _ ->
191+ let xs = [| 1 ; 2 ; 3 ; 4 ; 5 |]
192+ let thirdItem = xs.Third
193+ Expect.equal thirdItem 3 " Expected Third to be equal to the third item in the Array"
194+
195+ testCase " Third setter changes third item on Array with 3 or more items" <| fun _ ->
196+ let xs = [| 1 ; 2 ; 3 ; 4 ; 5 |]
197+ xs.Third <- 6
198+ Expect.equal xs.Third 6 " Expected Third to be changed to the new value"
199+
200+ testCase " Third getter on empty Array raises exception" <| fun _ ->
201+ let xs : int [] = [||]
202+ let testCode = fun () -> xs.Third |> ignore
203+ Expect.throws testCode " Expected an IndexOutOfRangeException"
181204
182205 //---- xs.IsEmpty ----
183206 testCase " IsEmpty returns true for empty Array" <| fun _ ->
@@ -265,4 +288,177 @@ module Extensions =
265288 let expected = " array<Int32> with 6 items:\n 0: 1\n 1: 2\n 2: 3\n ...\n 5: 6"
266289 Expect.equal s expected " toString entries"
267290
291+ //---- xs.FailIfEmpty ----
292+ testCase " FailIfEmpty returns array when not empty" <| fun _ ->
293+ let xs = [| 1 ; 2 ; 3 |]
294+ let result = xs.FailIfEmpty( " should not throw" )
295+ Expect.equal xs result " Expected same array to be returned"
296+
297+ testCase " FailIfEmpty throws on empty Array" <| fun _ ->
298+ let xs : int [] = [||]
299+ let testCode = fun () -> xs.FailIfEmpty( " is empty" ) |> ignore
300+ Expect.throws testCode " Expected an Exception on empty array"
301+
302+ //---- xs.FailIfLessThan ----
303+ testCase " FailIfLessThan returns array when count is sufficient" <| fun _ ->
304+ let xs = [| 1 ; 2 ; 3 |]
305+ let result = xs.FailIfLessThan( 3 , " should not throw" )
306+ Expect.equal xs result " Expected same array to be returned"
307+
308+ testCase " FailIfLessThan throws when count is insufficient" <| fun _ ->
309+ let xs = [| 1 ; 2 |]
310+ let testCode = fun () -> xs.FailIfLessThan( 3 , " too few" ) |> ignore
311+ Expect.throws testCode " Expected an Exception when array has too few items"
312+
313+ testCase " FailIfLessThan returns array when count exceeds minimum" <| fun _ ->
314+ let xs = [| 1 ; 2 ; 3 ; 4 ; 5 |]
315+ let result = xs.FailIfLessThan( 3 , " should not throw" )
316+ Expect.equal xs result " Expected same array to be returned"
317+
318+ //---- xs.HasItems ----
319+ testCase " HasItems returns true for non-empty Array" <| fun _ ->
320+ let xs = [| 1 ; 2 ; 3 |]
321+ Expect.isTrue xs.HasItems " Expected HasItems to be true for a non-empty Array"
322+
323+ testCase " HasItems returns false for empty Array" <| fun _ ->
324+ let xs : int [] = [||]
325+ Expect.isFalse xs.HasItems " Expected HasItems to be false for an empty Array"
326+
327+ //---- Immutability tests for extension members ----
328+ testCase " Get does not modify input array" <| fun _ ->
329+ let xs = [| 1 ; 2 ; 3 |]
330+ let original = xs.Duplicate()
331+ let _ = xs.Get 1
332+ Expect.isTrue ( xs = original) " Get should not modify input array"
333+
334+ testCase " GetNeg does not modify input array" <| fun _ ->
335+ let xs = [| 1 ; 2 ; 3 |]
336+ let original = xs.Duplicate()
337+ let _ = xs.GetNeg - 1
338+ Expect.isTrue ( xs = original) " GetNeg should not modify input array"
339+
340+ testCase " GetLooped does not modify input array" <| fun _ ->
341+ let xs = [| 1 ; 2 ; 3 |]
342+ let original = xs.Duplicate()
343+ let _ = xs.GetLooped 5
344+ Expect.isTrue ( xs = original) " GetLooped should not modify input array"
345+
346+ testCase " Duplicate creates independent copy" <| fun _ ->
347+ let xs = [| 1 ; 2 ; 3 |]
348+ let dup = xs.Duplicate()
349+ dup.[ 0 ] <- 99
350+ Expect.equal xs.[ 0 ] 1 " Original array should not be modified when duplicate is changed"
351+
352+ testCase " Slice does not modify input array" <| fun _ ->
353+ let xs = [| 1 ; 2 ; 3 ; 4 ; 5 |]
354+ let original = xs.Duplicate()
355+ let _ = xs.Slice( 1 , 3 )
356+ Expect.isTrue ( xs = original) " Slice should not modify input array"
357+
358+ testCase " First getter does not modify input array" <| fun _ ->
359+ let xs = [| 1 ; 2 ; 3 |]
360+ let original = xs.Duplicate()
361+ let _ = xs.First
362+ Expect.isTrue ( xs = original) " First getter should not modify input array"
363+
364+ testCase " Last getter does not modify input array" <| fun _ ->
365+ let xs = [| 1 ; 2 ; 3 |]
366+ let original = xs.Duplicate()
367+ let _ = xs.Last
368+ Expect.isTrue ( xs = original) " Last getter should not modify input array"
369+
370+ //---- Additional edge cases ----
371+ testCase " DebugIndexer throws on negative index" <| fun _ ->
372+ let xs = [| 1 ; 2 ; 3 |]
373+ let testCode = fun () -> xs.DebugIdx.[- 1 ] |> ignore
374+ Expect.throws testCode " Expected an IndexOutOfRangeException"
375+
376+ testCase " Idx gets item at index" <| fun _ ->
377+ let xs = [| 1 ; 2 ; 3 |]
378+ Expect.equal ( xs.Idx 1 ) 2 " Idx should return the item at index"
379+
380+ testCase " Idx throws on invalid index" <| fun _ ->
381+ let xs = [| 1 ; 2 ; 3 |]
382+ let testCode = fun () -> xs.Idx 3 |> ignore
383+ Expect.throws testCode " Expected an IndexOutOfRangeException"
384+
385+ testCase " GetNeg with boundary negative index" <| fun _ ->
386+ let xs = [| 1 ; 2 ; 3 |]
387+ Expect.equal ( xs.GetNeg - 3 ) 1 " GetNeg -3 should return first item"
388+
389+ testCase " GetNeg throws when negative index is too large" <| fun _ ->
390+ let xs = [| 1 ; 2 ; 3 |]
391+ let testCode = fun () -> xs.GetNeg - 4 |> ignore
392+ Expect.throws testCode " Expected an IndexOutOfRangeException"
393+
394+ testCase " SetNeg with boundary negative index" <| fun _ ->
395+ let xs = [| 1 ; 2 ; 3 |]
396+ xs.SetNeg - 3 99
397+ Expect.equal xs.[ 0 ] 99 " SetNeg -3 should set first item"
398+
399+ testCase " SetNeg throws when negative index is too large" <| fun _ ->
400+ let xs = [| 1 ; 2 ; 3 |]
401+ let testCode = fun () -> xs.SetNeg - 4 99
402+ Expect.throws testCode " Expected an IndexOutOfRangeException"
403+
404+ testCase " GetLooped with large positive index" <| fun _ ->
405+ let xs = [| 1 ; 2 ; 3 |]
406+ Expect.equal ( xs.GetLooped 100 ) ( xs.[ 100 % 3 ]) " GetLooped should wrap large positive index"
407+
408+ testCase " GetLooped with large negative index" <| fun _ ->
409+ let xs = [| 1 ; 2 ; 3 |]
410+ let expected = xs.[((- 100 % 3 ) + 3 ) % 3 ]
411+ Expect.equal ( xs.GetLooped - 100 ) expected " GetLooped should wrap large negative index"
412+
413+ testCase " SetLooped with large positive index" <| fun _ ->
414+ let xs = [| 1 ; 2 ; 3 |]
415+ xs.SetLooped 100 99
416+ Expect.equal xs.[ 100 % 3 ] 99 " SetLooped should wrap large positive index"
417+
418+ testCase " Slice with negative start and positive end" <| fun _ ->
419+ let xs = [| 1 ; 2 ; 3 ; 4 ; 5 |]
420+ let result = xs.Slice(- 3 , 4 )
421+ Expect.isTrue ( result = [| 3 ; 4 ; 5 |]) " Slice should work with mixed indices"
422+
423+ testCase " Slice throws when start is after end" <| fun _ ->
424+ let xs = [| 1 ; 2 ; 3 ; 4 ; 5 |]
425+ let testCode = fun () -> xs.Slice( 3 , 1 ) |> ignore
426+ Expect.throws testCode " Expected an IndexOutOfRangeException"
427+
428+ testCase " Slice throws when indices are out of bounds" <| fun _ ->
429+ let xs = [| 1 ; 2 ; 3 |]
430+ let testCode1 = fun () -> xs.Slice( 5 , 6 ) |> ignore
431+ let testCode2 = fun () -> xs.Slice( 0 , 5 ) |> ignore
432+ Expect.throws testCode1 " Expected an IndexOutOfRangeException for start out of bounds"
433+ Expect.throws testCode2 " Expected an IndexOutOfRangeException for end out of bounds"
434+
435+ testCase " IsSingleton returns false for empty Array" <| fun _ ->
436+ let xs : int [] = [||]
437+ Expect.isFalse xs.IsSingleton " Expected IsSingleton to be false for an empty Array"
438+
439+ testCase " LastIndex returns correct value for various arrays" <| fun _ ->
440+ Expect.equal [| 1 |]. LastIndex 0 " Single item array should have LastIndex 0"
441+ Expect.equal [| 1 ; 2 ; 3 |]. LastIndex 2 " Three item array should have LastIndex 2"
442+
443+ testCase " FirstAndOnly fails on empty Array" <| fun _ ->
444+ let xs : int [] = [||]
445+ let testCode = fun () -> xs.FirstAndOnly |> ignore
446+ Expect.throws testCode " Expected an IndexOutOfRangeException"
447+
448+ testCase " SecondLast on two item Array" <| fun _ ->
449+ let xs = [| 1 ; 2 |]
450+ Expect.equal xs.SecondLast 1 " SecondLast on two item array should return first item"
451+
452+ testCase " ThirdLast on three item Array" <| fun _ ->
453+ let xs = [| 1 ; 2 ; 3 |]
454+ Expect.equal xs.ThirdLast 1 " ThirdLast on three item array should return first item"
455+
456+ testCase " Second on two item Array" <| fun _ ->
457+ let xs = [| 1 ; 2 |]
458+ Expect.equal xs.Second 2 " Second on two item array should return second item"
459+
460+ testCase " Third on three item Array" <| fun _ ->
461+ let xs = [| 1 ; 2 ; 3 |]
462+ Expect.equal xs.Third 3 " Third on three item array should return third item"
463+
268464 ]
0 commit comments