Skip to content

Commit a1b4b75

Browse files
committed
Add comprehensive tests for CSV extension methods AsTimeSpan and AsDateTimeOffset
- Add 10 new test cases covering AsTimeSpan() and AsDateTimeOffset() extension methods in CSV context - Test valid inputs with different time formats (simple, complex, with milliseconds) - Test DateTimeOffset parsing with positive, negative, and zero UTC offsets - Test error handling for invalid input strings - Test culture-specific parsing scenarios - Test integration with CSV dynamic operator (?) - Addresses test coverage gap identified for these extension methods This improves test coverage for CSV extension methods that were previously untested in the CSV context, even though the underlying functionality was tested elsewhere. Total test count increased from 2393 to 2403 tests, all passing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5f4773c commit a1b4b75

1 file changed

Lines changed: 91 additions & 1 deletion

File tree

tests/FSharp.Data.Core.Tests/CsvFile.fs

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,94 @@ let ``Complex CSV with quotes and newlines handled correctly`` () =
262262
rows.[0].["Name"] |> should equal "Alice"
263263
rows.[0].["Description"] |> should equal "Software Engineer, Senior"
264264
rows.[1].["Description"] |> should equal "Product Manager\"s Assistant"
265-
rows.[2].["Description"] |> should equal "Data Scientist\nwith ML focus"
265+
rows.[2].["Description"] |> should equal "Data Scientist\nwith ML focus"
266+
267+
// Sample CSV data with time/date fields for testing extension methods
268+
let csvWithDateTimeData = """StartDate,EndDate,Duration,Offset
269+
2023-01-15,2023-01-20,5.00:00:00,2023-01-15T10:30:00+02:00
270+
2023-02-01,2023-02-03,2.12:30:45,2023-02-01T14:15:30-05:00
271+
2023-03-10,2023-03-15,4.08:15:20,2023-03-10T09:45:00+00:00"""
272+
273+
// StringExtensions tests for CSV context - Missing coverage area
274+
[<Test>]
275+
let ``StringExtensions.AsTimeSpan works with valid input`` () =
276+
let csv = CsvFile.Parse(csvWithDateTimeData)
277+
let firstRow = csv.Rows |> Seq.head
278+
279+
firstRow.["Duration"].AsTimeSpan() |> should equal (System.TimeSpan(5, 0, 0, 0))
280+
281+
[<Test>]
282+
let ``StringExtensions.AsTimeSpan works with complex time format`` () =
283+
let csv = CsvFile.Parse(csvWithDateTimeData)
284+
let rows = csv.Rows |> Array.ofSeq
285+
286+
rows.[1].["Duration"].AsTimeSpan() |> should equal (System.TimeSpan(2, 12, 30, 45))
287+
rows.[2].["Duration"].AsTimeSpan() |> should equal (System.TimeSpan(4, 8, 15, 20))
288+
289+
[<Test>]
290+
let ``StringExtensions.AsTimeSpan throws with invalid input`` () =
291+
let csv = CsvFile.Parse("InvalidTime\ninvalid_time")
292+
let row = csv.Rows |> Seq.head
293+
294+
Assert.Throws<System.Exception>(fun () -> row.["InvalidTime"].AsTimeSpan() |> ignore) |> ignore
295+
296+
[<Test>]
297+
let ``StringExtensions.AsDateTimeOffset works with valid input`` () =
298+
let csv = CsvFile.Parse(csvWithDateTimeData)
299+
let firstRow = csv.Rows |> Seq.head
300+
301+
let result = firstRow.["Offset"].AsDateTimeOffset()
302+
result.DateTime |> should equal (System.DateTime(2023, 1, 15, 10, 30, 0))
303+
result.Offset |> should equal (System.TimeSpan(2, 0, 0))
304+
305+
[<Test>]
306+
let ``StringExtensions.AsDateTimeOffset works with negative offset`` () =
307+
let csv = CsvFile.Parse(csvWithDateTimeData)
308+
let rows = csv.Rows |> Array.ofSeq
309+
310+
let result = rows.[1].["Offset"].AsDateTimeOffset()
311+
result.DateTime |> should equal (System.DateTime(2023, 2, 1, 14, 15, 30))
312+
result.Offset |> should equal (System.TimeSpan(-5, 0, 0))
313+
314+
[<Test>]
315+
let ``StringExtensions.AsDateTimeOffset works with zero offset`` () =
316+
let csv = CsvFile.Parse(csvWithDateTimeData)
317+
let rows = csv.Rows |> Array.ofSeq
318+
319+
let result = rows.[2].["Offset"].AsDateTimeOffset()
320+
result.DateTime |> should equal (System.DateTime(2023, 3, 10, 9, 45, 0))
321+
result.Offset |> should equal (System.TimeSpan.Zero)
322+
323+
[<Test>]
324+
let ``StringExtensions.AsDateTimeOffset throws with invalid input`` () =
325+
let csv = CsvFile.Parse("InvalidOffset\ninvalid_offset")
326+
let row = csv.Rows |> Seq.head
327+
328+
Assert.Throws<System.Exception>(fun () -> row.["InvalidOffset"].AsDateTimeOffset() |> ignore) |> ignore
329+
330+
[<Test>]
331+
let ``StringExtensions.AsTimeSpan with custom culture`` () =
332+
let csv = CsvFile.Parse("Duration\n01:30:45")
333+
let row = csv.Rows |> Seq.head
334+
335+
let result = row.["Duration"].AsTimeSpan(System.Globalization.CultureInfo.InvariantCulture)
336+
result |> should equal (System.TimeSpan(1, 30, 45))
337+
338+
[<Test>]
339+
let ``StringExtensions.AsDateTimeOffset with custom culture`` () =
340+
let csv = CsvFile.Parse("Timestamp\n2023-06-15T16:20:30+03:00")
341+
let row = csv.Rows |> Seq.head
342+
343+
let result = row.["Timestamp"].AsDateTimeOffset(System.Globalization.CultureInfo.InvariantCulture)
344+
result.DateTime |> should equal (System.DateTime(2023, 6, 15, 16, 20, 30))
345+
result.Offset |> should equal (System.TimeSpan(3, 0, 0))
346+
347+
[<Test>]
348+
let ``StringExtensions methods work with dynamic operator`` () =
349+
let csv = CsvFile.Parse(csvWithDateTimeData)
350+
let row = csv.Rows |> Seq.head
351+
352+
// Test that the ? operator integrates properly with extension methods
353+
row?Duration.AsTimeSpan() |> should equal (System.TimeSpan(5, 0, 0, 0))
354+
let offsetResult = row?Offset.AsDateTimeOffset()
355+
offsetResult.Offset |> should equal (System.TimeSpan(2, 0, 0))

0 commit comments

Comments
 (0)