1+ package io .github .quafadas .scautable
2+
3+ import io .github .quafadas .table .*
4+
5+
6+ class CSVWriterSuite extends munit.FunSuite :
7+
8+ test(" CSVWriter.formatField handles simple fields" ) {
9+ assertEquals(CSVWriter .formatField(" hello" ), " hello" )
10+ assertEquals(CSVWriter .formatField(" 123" ), " 123" )
11+ assertEquals(CSVWriter .formatField(" " ), " " )
12+ }
13+
14+ test(" CSVWriter.formatField quotes fields with commas" ) {
15+ assertEquals(CSVWriter .formatField(" hello,world" ), " \" hello,world\" " )
16+ assertEquals(CSVWriter .formatField(" a,b,c" ), " \" a,b,c\" " )
17+ }
18+
19+ test(" CSVWriter.formatField escapes quotes" ) {
20+ assertEquals(CSVWriter .formatField(" say \" hello\" " ), " \" say \"\" hello\"\"\" " )
21+ assertEquals(CSVWriter .formatField(" \" quoted\" " ), " \"\"\" quoted\"\"\" " )
22+ }
23+
24+ test(" CSVWriter.formatField quotes fields with newlines" ) {
25+ assertEquals(CSVWriter .formatField(" line1\n line2" ), " \" line1\n line2\" " )
26+ assertEquals(CSVWriter .formatField(" line1\r line2" ), " \" line1\r line2\" " )
27+ }
28+
29+ test(" CSVWriter.formatField quotes fields with leading/trailing spaces" ) {
30+ assertEquals(CSVWriter .formatField(" hello" ), " \" hello\" " )
31+ assertEquals(CSVWriter .formatField(" hello " ), " \" hello \" " )
32+ assertEquals(CSVWriter .formatField(" hello " ), " \" hello \" " )
33+ }
34+
35+ test(" CSVWriter.formatLine formats simple line" ) {
36+ assertEquals(CSVWriter .formatLine(Seq (" a" , " b" , " c" )), " a,b,c" )
37+ assertEquals(CSVWriter .formatLine(Seq (" 1" , " 2" , " 3" )), " 1,2,3" )
38+ }
39+
40+ test(" CSVWriter.formatLine handles complex line" ) {
41+ assertEquals(
42+ CSVWriter .formatLine(Seq (" hello,world" , " say \" hi\" " , " normal" )),
43+ " \" hello,world\" ,\" say \"\" hi\"\"\" ,normal"
44+ )
45+ }
46+
47+ test(" CSVWriter.formatLine with custom delimiter" ) {
48+ assertEquals(CSVWriter .formatLine(Seq (" a" , " b" , " c" ), delimiter = ';' ), " a;b;c" )
49+ assertEquals(CSVWriter .formatLine(Seq (" a;b" , " c" ), delimiter = ';' ), " \" a;b\" ;c" )
50+ }
51+
52+ test(" Iterator[NamedTuple].toCsv basic functionality" ) {
53+ val data = Iterator (
54+ (col1 = " 1" , col2 = " 2" , col3 = " 7" ),
55+ (col1 = " 3" , col2 = " 4" , col3 = " 8" ),
56+ (col1 = " 5" , col2 = " 6" , col3 = " 9" )
57+ )
58+
59+ val expected = Seq (" col1,col2,col3" ,
60+ " 1,2,7" ,
61+ " 3,4,8" ,
62+ " 5,6,9" )
63+
64+ assertEquals(
65+ data.toCsv(includeHeaders = true , ',' , '"'
66+ ).toSeq, expected)
67+ }
68+
69+ test(" Iterator[NamedTuple].toCsv without headers" ) {
70+ val data = Iterator (
71+ (col1 = " 1" , col2 = " 2" , col3 = " 7" ),
72+ (col1 = " 3" , col2 = " 4" , col3 = " 8" )
73+ )
74+
75+ val expected = Seq (" 1,2,7" , " 3,4,8" )
76+
77+ assertEquals(
78+ data.toCsv(includeHeaders = false , ',' , '"' ).toSeq,
79+ expected
80+ )
81+ }
82+
83+ test(" Iterator[NamedTuple].toCsv with custom delimiter" ) {
84+ val data = Iterator (
85+ (col1 = " 1" , col2 = " 2" ),
86+ (col1 = " 3" , col2 = " 4" )
87+ )
88+
89+ val expected = Seq (
90+ """ col1;col2""" ,
91+ """ 1;2""" ,
92+ """ 3;4""" )
93+
94+ assertEquals(data.toCsv(delimiter = ';' ).toSeq, expected)
95+ }
96+
97+ test(" Seq[NamedTuple].toCsv basic functionality" ) {
98+ val data = Seq (
99+ (col1 = " 1" , col2 = " 2" , col3 = " 7" ),
100+ (col1 = " 3" , col2 = " 4" , col3 = " 8" ),
101+ (col1 = " 5" , col2 = " 6" , col3 = " 9" )
102+ )
103+
104+ val expected = """ col1,col2,col3
105+ 1,2,7
106+ 3,4,8
107+ 5,6,9"""
108+
109+ assertEquals(data.toCsv(true , ',' , '"' ), expected)
110+ }
111+
112+ test(" List[NamedTuple].toCsv with empty values" ) {
113+ val data = List (
114+ (col1 = " " , col2 = " 2" , col3 = " 7" ),
115+ (col1 = " 3" , col2 = " " , col3 = " 8" ),
116+ (col1 = " 5" , col2 = " 6" , col3 = " " )
117+ )
118+
119+ val expected = """ col1,col2,col3
120+ ,2,7
121+ 3,,8
122+ 5,6,"""
123+
124+ assertEquals(data.toCsv(true , ',' , '"' ), expected)
125+ }
126+
127+ test(" Vector[NamedTuple].toCsv with numeric types" ) {
128+ val data = Vector (
129+ (id = 1 , name = " Alice" , score = 95.5 ),
130+ (id = 2 , name = " Bob" , score = 87.1 )
131+ )
132+
133+ val expected = """ id,name,score
134+ 1,Alice,95.5
135+ 2,Bob,87.1"""
136+
137+ assertEquals(data.toCsv(true , ',' , '"' ), expected)
138+ }
139+
140+ test(" empty collection toCsv" ) {
141+ // Note: This test requires the type to be explicit since we can't infer from empty collections
142+ val data : List [(col1 : String , col2 : String )] = List .empty
143+ val expected = " col1,col2"
144+
145+ assertEquals(data.toCsv(true , ',' , '"' ), expected)
146+ }
147+
148+ test(" empty collection toCsv without headers" ) {
149+ val data : List [(col1 : String , col2 : String )] = List .empty
150+ assertEquals(data.toCsv(false , ',' , '"' ), " " )
151+ }
152+
153+ end CSVWriterSuite
0 commit comments