├── .gitignore ├── DataTablePrettyPrinter.Tests ├── DataTablePrettyPrinter.Tests.csproj ├── GlobalSuppressions.cs ├── TestDataColumnExtensions.cs ├── TestDataTableExtensions.cs └── TestUtilities.cs ├── DataTablePrettyPrinter.sln ├── DataTablePrettyPrinter ├── Border.cs ├── CharExtensions.cs ├── DataColumnExtensions.cs ├── DataRowExtensions.cs ├── DataTableExtensions.cs ├── DataTablePrettyPrinter.csproj ├── GlobalSuppressions.cs ├── TextAlignment.cs └── Utilities.cs ├── LICENSE ├── README.md └── azure-pipelines.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio 2 | **/.vs/** 3 | **/bin/ 4 | **/obj/ -------------------------------------------------------------------------------- /DataTablePrettyPrinter.Tests/DataTablePrettyPrinter.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter.Tests/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header")] 9 | [assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:Prefix local calls with this")] 10 | [assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1404:Code analysis suppression should have justification")] 11 | [assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:Parameters should be on same line or separate lines")] 12 | [assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented")] 13 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter.Tests/TestDataColumnExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter.Tests 2 | { 3 | using System; 4 | using Xunit; 5 | 6 | public class TestDataColumnExtensions 7 | { 8 | [Fact] 9 | public void TestDataBorder() 10 | { 11 | var table = TestUtilities.CreateTypicalTable(); 12 | 13 | Assert.Equal(Border.All, table.Columns[0].GetDataBorder()); 14 | Assert.Equal( 15 | @" 16 | +-----------------------------------------------------------+ 17 | | Prescriptions | 18 | +--------+-------------+-----------+------------------------+ 19 | | Dosage | Drug | Patient | Date | 20 | +--------+-------------+-----------+------------------------+ 21 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 22 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 23 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 24 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 25 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 26 | +--------+-------------+-----------+------------------------+" 27 | 28 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 29 | 30 | table.Columns[0].SetDataBorder(Border.Left); 31 | Assert.Equal(Border.Left, table.Columns[0].GetDataBorder()); 32 | Assert.Equal( 33 | @" 34 | +-----------------------------------------------------------+ 35 | | Prescriptions | 36 | +--------+-------------+-----------+------------------------+ 37 | | Dosage | Drug | Patient | Date | 38 | +--------+-------------+-----------+------------------------+ 39 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 40 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 41 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 42 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 43 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 44 | +--------+-------------+-----------+------------------------+" 45 | 46 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 47 | 48 | table.Columns[0].SetDataBorder(Border.Left); 49 | table.Columns[1].SetDataBorder(Border.Right); 50 | Assert.Equal(Border.Left, table.Columns[0].GetDataBorder()); 51 | Assert.Equal(Border.Right, table.Columns[1].GetDataBorder()); 52 | Assert.Equal( 53 | @" 54 | +-----------------------------------------------------------+ 55 | | Prescriptions | 56 | +--------+-------------+-----------+------------------------+ 57 | | Dosage | Drug | Patient | Date | 58 | +--------+-------------+-----------+------------------------+ 59 | | 25 Indocin | David | 0001-01-01 12:00:12 AM | 60 | | 50 Enebrel | Sam | 0001-01-01 12:00:12 AM | 61 | | 10 Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 62 | | 21 Combivent | Janet | 0001-01-01 12:00:12 AM | 63 | | 100 Dilantin | Melanie | 0001-01-01 12:00:12 AM | 64 | +----------------------+-----------+------------------------+" 65 | 66 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 67 | 68 | table.SetBorder(Border.Top | Border.Right); 69 | table.Columns[0].SetDataBorder(Border.Left | Border.Bottom); 70 | table.Columns[1].SetDataBorder(Border.Right); 71 | Assert.Equal(Border.Left | Border.Bottom, table.Columns[0].GetDataBorder()); 72 | Assert.Equal(Border.Right, table.Columns[1].GetDataBorder()); 73 | Assert.Equal( 74 | @" 75 | +-----------------------------------------------------------+ 76 | Prescriptions | 77 | +--------+-------------+-----------+------------------------+ 78 | | Dosage | Drug | Patient | Date | 79 | +--------+-------------+-----------+------------------------+ 80 | | 25 Indocin | David | 0001-01-01 12:00:12 AM | 81 | | 50 Enebrel | Sam | 0001-01-01 12:00:12 AM | 82 | | 10 Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 83 | | 21 Combivent | Janet | 0001-01-01 12:00:12 AM | 84 | | 100 Dilantin | Melanie | 0001-01-01 12:00:12 AM | 85 | +--------+ +-----------+------------------------+" 86 | 87 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 88 | } 89 | 90 | [Fact] 91 | public void TestDataBorderOnTypicalTableWithoutBorders() 92 | { 93 | var table = TestUtilities.CreateTypicalTableWithoutBorders(); 94 | 95 | Assert.Equal(Border.None, table.Columns[0].GetDataBorder()); 96 | Assert.Equal( 97 | @" 98 | 99 | Prescriptions 100 | 101 | Dosage Drug Patient Date 102 | 103 | 25 Indocin David 0001-01-01 12:00:12 AM 104 | 50 Enebrel Sam 0001-01-01 12:00:12 AM 105 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM 106 | 21 Combivent Janet 0001-01-01 12:00:12 AM 107 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM 108 | " 109 | 110 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 111 | 112 | table.Columns[0].SetDataBorder(Border.All); 113 | Assert.Equal(Border.All, table.Columns[0].GetDataBorder()); 114 | Assert.Equal( 115 | @" 116 | 117 | Prescriptions 118 | 119 | Dosage Drug Patient Date 120 | +--------+ 121 | | 25 | Indocin David 0001-01-01 12:00:12 AM 122 | | 50 | Enebrel Sam 0001-01-01 12:00:12 AM 123 | | 10 | Hydralazine Christoff 0001-01-01 12:00:12 AM 124 | | 21 | Combivent Janet 0001-01-01 12:00:12 AM 125 | | 100 | Dilantin Melanie 0001-01-01 12:00:12 AM 126 | +--------+ " 127 | 128 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 129 | 130 | table.Columns[0].SetDataBorder(Border.Left); 131 | table.Columns[1].SetDataBorder(Border.Right | Border.Bottom); 132 | Assert.Equal(Border.Left, table.Columns[0].GetDataBorder()); 133 | Assert.Equal(Border.Right | Border.Bottom, table.Columns[1].GetDataBorder()); 134 | Assert.Equal( 135 | @" 136 | 137 | Prescriptions 138 | 139 | Dosage Drug Patient Date 140 | + + 141 | | 25 Indocin | David 0001-01-01 12:00:12 AM 142 | | 50 Enebrel | Sam 0001-01-01 12:00:12 AM 143 | | 10 Hydralazine | Christoff 0001-01-01 12:00:12 AM 144 | | 21 Combivent | Janet 0001-01-01 12:00:12 AM 145 | | 100 Dilantin | Melanie 0001-01-01 12:00:12 AM 146 | + +-------------+ " 147 | 148 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 149 | 150 | table.SetBorder(Border.All); 151 | table.Columns[0].SetDataBorder(Border.Top); 152 | table.Columns[1].SetDataBorder(Border.Top); 153 | table.Columns[2].SetDataBorder(Border.Top); 154 | table.Columns[3].SetDataBorder(Border.Top); 155 | Assert.Equal(Border.Top, table.Columns[0].GetDataBorder()); 156 | Assert.Equal(Border.Top, table.Columns[1].GetDataBorder()); 157 | Assert.Equal(Border.Top, table.Columns[2].GetDataBorder()); 158 | Assert.Equal(Border.Top, table.Columns[3].GetDataBorder()); 159 | Assert.Equal( 160 | @" 161 | +-----------------------------------------------------------+ 162 | | Prescriptions | 163 | | | 164 | | Dosage Drug Patient Date | 165 | +--------+-------------+-----------+------------------------+ 166 | | 25 Indocin David 0001-01-01 12:00:12 AM | 167 | | 50 Enebrel Sam 0001-01-01 12:00:12 AM | 168 | | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM | 169 | | 21 Combivent Janet 0001-01-01 12:00:12 AM | 170 | | 100 Dilantin Melanie 0001-01-01 12:00:12 AM | 171 | +-----------------------------------------------------------+" 172 | 173 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 174 | 175 | table.SetBorder(Border.All); 176 | table.Columns[0].SetDataBorder(Border.Top | Border.Bottom); 177 | table.Columns[1].SetDataBorder(Border.Top); 178 | table.Columns[2].SetDataBorder(Border.Top); 179 | table.Columns[3].SetDataBorder(Border.Top | Border.Bottom); 180 | Assert.Equal(Border.Top | Border.Bottom, table.Columns[0].GetDataBorder()); 181 | Assert.Equal(Border.Top, table.Columns[1].GetDataBorder()); 182 | Assert.Equal(Border.Top, table.Columns[2].GetDataBorder()); 183 | Assert.Equal(Border.Top | Border.Bottom, table.Columns[3].GetDataBorder()); 184 | Assert.Equal( 185 | @" 186 | +-----------------------------------------------------------+ 187 | | Prescriptions | 188 | | | 189 | | Dosage Drug Patient Date | 190 | +--------+-------------+-----------+------------------------+ 191 | | 25 Indocin David 0001-01-01 12:00:12 AM | 192 | | 50 Enebrel Sam 0001-01-01 12:00:12 AM | 193 | | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM | 194 | | 21 Combivent Janet 0001-01-01 12:00:12 AM | 195 | | 100 Dilantin Melanie 0001-01-01 12:00:12 AM | 196 | +--------+-------------------------+------------------------+" 197 | 198 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 199 | } 200 | 201 | [Fact] 202 | public void TestDataAlignment() 203 | { 204 | var table = TestUtilities.CreateTypicalTable(); 205 | 206 | Assert.Equal(TextAlignment.Left, table.Columns[0].GetDataAlignment()); 207 | Assert.Equal( 208 | @" 209 | +-----------------------------------------------------------+ 210 | | Prescriptions | 211 | +--------+-------------+-----------+------------------------+ 212 | | Dosage | Drug | Patient | Date | 213 | +--------+-------------+-----------+------------------------+ 214 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 215 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 216 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 217 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 218 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 219 | +--------+-------------+-----------+------------------------+" 220 | 221 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 222 | 223 | table.Columns[0].SetDataAlignment(TextAlignment.Center); 224 | Assert.Equal(TextAlignment.Center, table.Columns[0].GetDataAlignment()); 225 | Assert.Equal( 226 | @" 227 | +-----------------------------------------------------------+ 228 | | Prescriptions | 229 | +--------+-------------+-----------+------------------------+ 230 | | Dosage | Drug | Patient | Date | 231 | +--------+-------------+-----------+------------------------+ 232 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 233 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 234 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 235 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 236 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 237 | +--------+-------------+-----------+------------------------+" 238 | 239 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 240 | 241 | table.Columns[0].SetDataAlignment(TextAlignment.Right); 242 | Assert.Equal(TextAlignment.Right, table.Columns[0].GetDataAlignment()); 243 | Assert.Equal( 244 | @" 245 | +-----------------------------------------------------------+ 246 | | Prescriptions | 247 | +--------+-------------+-----------+------------------------+ 248 | | Dosage | Drug | Patient | Date | 249 | +--------+-------------+-----------+------------------------+ 250 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 251 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 252 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 253 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 254 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 255 | +--------+-------------+-----------+------------------------+" 256 | 257 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 258 | 259 | table.Columns[0].SetDataAlignment(TextAlignment.Right); 260 | table.Columns[1].SetDataAlignment(TextAlignment.Center); 261 | table.Columns[2].SetDataAlignment(TextAlignment.Right); 262 | table.Columns[3].SetDataAlignment(TextAlignment.Center); 263 | Assert.Equal(TextAlignment.Right, table.Columns[0].GetDataAlignment()); 264 | Assert.Equal(TextAlignment.Center, table.Columns[1].GetDataAlignment()); 265 | Assert.Equal(TextAlignment.Right, table.Columns[2].GetDataAlignment()); 266 | Assert.Equal(TextAlignment.Center, table.Columns[3].GetDataAlignment()); 267 | Assert.Equal( 268 | @" 269 | +-----------------------------------------------------------+ 270 | | Prescriptions | 271 | +--------+-------------+-----------+------------------------+ 272 | | Dosage | Drug | Patient | Date | 273 | +--------+-------------+-----------+------------------------+ 274 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 275 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 276 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 277 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 278 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 279 | +--------+-------------+-----------+------------------------+" 280 | 281 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 282 | } 283 | 284 | [Fact] 285 | public void TestDataTextFormat() 286 | { 287 | var table = TestUtilities.CreateTypicalTable(); 288 | 289 | table.Columns[0].SetDataTextFormat((c, r) => "5"); 290 | Assert.Equal( 291 | @" 292 | +-----------------------------------------------------------+ 293 | | Prescriptions | 294 | +--------+-------------+-----------+------------------------+ 295 | | Dosage | Drug | Patient | Date | 296 | +--------+-------------+-----------+------------------------+ 297 | | 5 | Indocin | David | 0001-01-01 12:00:12 AM | 298 | | 5 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 299 | | 5 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 300 | | 5 | Combivent | Janet | 0001-01-01 12:00:12 AM | 301 | | 5 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 302 | +--------+-------------+-----------+------------------------+" 303 | 304 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 305 | 306 | table.Columns[0].SetDataTextFormat((c, r) => "1234567890"); 307 | Assert.Equal( 308 | @" 309 | +---------------------------------------------------------------+ 310 | | Prescriptions | 311 | +------------+-------------+-----------+------------------------+ 312 | | Dosage | Drug | Patient | Date | 313 | +------------+-------------+-----------+------------------------+ 314 | | 1234567890 | Indocin | David | 0001-01-01 12:00:12 AM | 315 | | 1234567890 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 316 | | 1234567890 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 317 | | 1234567890 | Combivent | Janet | 0001-01-01 12:00:12 AM | 318 | | 1234567890 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 319 | +------------+-------------+-----------+------------------------+" 320 | 321 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 322 | 323 | table.Columns[0].SetDataTextFormat((c, r) => "1234567890"); 324 | table.Columns[1].SetDataTextFormat((c, r) => r[c].ToString().Length.ToString()); 325 | Assert.Equal( 326 | @" 327 | +--------------------------------------------------------+ 328 | | Prescriptions | 329 | +------------+------+-----------+------------------------+ 330 | | Dosage | Drug | Patient | Date | 331 | +------------+------+-----------+------------------------+ 332 | | 1234567890 | 7 | David | 0001-01-01 12:00:12 AM | 333 | | 1234567890 | 7 | Sam | 0001-01-01 12:00:12 AM | 334 | | 1234567890 | 11 | Christoff | 0001-01-01 12:00:12 AM | 335 | | 1234567890 | 9 | Janet | 0001-01-01 12:00:12 AM | 336 | | 1234567890 | 8 | Melanie | 0001-01-01 12:00:12 AM | 337 | +------------+------+-----------+------------------------+" 338 | 339 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 340 | 341 | table.Columns[0].SetDataTextFormat((c, r) => string.Format("0x{0:X4}", r[c])); 342 | table.Columns[1].SetDataTextFormat((c, r) => r[c].ToString().Length.ToString()); 343 | table.Columns[2].SetDataTextFormat((c, r) => 344 | { 345 | if (table.Rows.IndexOf(r) == 3) 346 | { 347 | return "My special name"; 348 | } 349 | else 350 | { 351 | return r[c].ToString(); 352 | } 353 | }); 354 | Assert.Equal( 355 | @" 356 | +----------------------------------------------------------+ 357 | | Prescriptions | 358 | +--------+------+-----------------+------------------------+ 359 | | Dosage | Drug | Patient | Date | 360 | +--------+------+-----------------+------------------------+ 361 | | 0x0019 | 7 | David | 0001-01-01 12:00:12 AM | 362 | | 0x0032 | 7 | Sam | 0001-01-01 12:00:12 AM | 363 | | 0x000A | 11 | Christoff | 0001-01-01 12:00:12 AM | 364 | | 0x0015 | 9 | My special name | 0001-01-01 12:00:12 AM | 365 | | 0x0064 | 8 | Melanie | 0001-01-01 12:00:12 AM | 366 | +--------+------+-----------------+------------------------+" 367 | 368 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 369 | } 370 | 371 | [Fact] 372 | public void TestDataTextFormatOrdinalNumber() 373 | { 374 | var table = TestUtilities.CreateTypicalTable(); 375 | 376 | table.Columns.Add("Index", typeof(int)).SetOrdinal(0); 377 | table.Columns[0].SetDataTextFormat((c, r) => table.Rows.IndexOf(r).ToString()); 378 | Assert.Equal( 379 | @" 380 | +-------------------------------------------------------------------+ 381 | | Prescriptions | 382 | +-------+--------+-------------+-----------+------------------------+ 383 | | Index | Dosage | Drug | Patient | Date | 384 | +-------+--------+-------------+-----------+------------------------+ 385 | | 0 | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 386 | | 1 | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 387 | | 2 | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 388 | | 3 | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 389 | | 4 | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 390 | +-------+--------+-------------+-----------+------------------------+" 391 | 392 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 393 | } 394 | 395 | [Fact] 396 | public void TestHeaderBorder() 397 | { 398 | var table = TestUtilities.CreateTypicalTable(); 399 | 400 | Assert.Equal(Border.All, table.Columns[0].GetHeaderBorder()); 401 | Assert.Equal( 402 | @" 403 | +-----------------------------------------------------------+ 404 | | Prescriptions | 405 | +--------+-------------+-----------+------------------------+ 406 | | Dosage | Drug | Patient | Date | 407 | +--------+-------------+-----------+------------------------+ 408 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 409 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 410 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 411 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 412 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 413 | +--------+-------------+-----------+------------------------+" 414 | 415 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 416 | 417 | table.Columns[0].SetHeaderBorder(Border.Bottom); 418 | Assert.Equal(Border.Bottom, table.Columns[0].GetHeaderBorder()); 419 | Assert.Equal( 420 | @" 421 | +-----------------------------------------------------------+ 422 | | Prescriptions | 423 | | +-------------+-----------+------------------------+ 424 | | Dosage | Drug | Patient | Date | 425 | +--------+-------------+-----------+------------------------+ 426 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 427 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 428 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 429 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 430 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 431 | +--------+-------------+-----------+------------------------+" 432 | 433 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 434 | 435 | table.Columns[0].SetHeaderBorder(Border.Bottom); 436 | table.Columns[1].SetHeaderBorder(Border.Top); 437 | table.Columns[2].SetHeaderBorder(Border.Left | Border.Bottom); 438 | table.Columns[3].SetHeaderBorder(Border.Right); 439 | Assert.Equal(Border.Bottom, table.Columns[0].GetHeaderBorder()); 440 | Assert.Equal(Border.Top, table.Columns[1].GetHeaderBorder()); 441 | Assert.Equal(Border.Left | Border.Bottom, table.Columns[2].GetHeaderBorder()); 442 | Assert.Equal(Border.Right, table.Columns[3].GetHeaderBorder()); 443 | Assert.Equal( 444 | @" 445 | +-----------------------------------------------------------+ 446 | | Prescriptions | 447 | | +-------------+ + 448 | | Dosage Drug | Patient Date | 449 | +--------+-------------+-----------+------------------------+ 450 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 451 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 452 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 453 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 454 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 455 | +--------+-------------+-----------+------------------------+" 456 | 457 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 458 | } 459 | 460 | [Fact] 461 | public void TestHeaderBorderOnTypicalTableWithoutBorders() 462 | { 463 | var table = TestUtilities.CreateTypicalTableWithoutBorders(); 464 | 465 | Assert.Equal(Border.None, table.Columns[0].GetHeaderBorder()); 466 | Assert.Equal( 467 | @" 468 | 469 | Prescriptions 470 | 471 | Dosage Drug Patient Date 472 | 473 | 25 Indocin David 0001-01-01 12:00:12 AM 474 | 50 Enebrel Sam 0001-01-01 12:00:12 AM 475 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM 476 | 21 Combivent Janet 0001-01-01 12:00:12 AM 477 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM 478 | " 479 | 480 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 481 | 482 | table.Columns[0].SetHeaderBorder(Border.Bottom); 483 | Assert.Equal(Border.Bottom, table.Columns[0].GetHeaderBorder()); 484 | Assert.Equal( 485 | @" 486 | 487 | Prescriptions 488 | 489 | Dosage Drug Patient Date 490 | +--------+ 491 | 25 Indocin David 0001-01-01 12:00:12 AM 492 | 50 Enebrel Sam 0001-01-01 12:00:12 AM 493 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM 494 | 21 Combivent Janet 0001-01-01 12:00:12 AM 495 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM 496 | " 497 | 498 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 499 | 500 | table.Columns[0].SetHeaderBorder(Border.Bottom | Border.Right); 501 | table.Columns[1].SetHeaderBorder(Border.Top); 502 | table.Columns[2].SetHeaderBorder(Border.Left | Border.Bottom); 503 | table.Columns[3].SetHeaderBorder(Border.Left | Border.Top | Border.Right); 504 | Assert.Equal(Border.Bottom | Border.Right, table.Columns[0].GetHeaderBorder()); 505 | Assert.Equal(Border.Top, table.Columns[1].GetHeaderBorder()); 506 | Assert.Equal(Border.Left | Border.Bottom, table.Columns[2].GetHeaderBorder()); 507 | Assert.Equal(Border.Left | Border.Top | Border.Right, table.Columns[3].GetHeaderBorder()); 508 | Assert.Equal( 509 | @" 510 | 511 | Prescriptions 512 | +-------------+ +------------------------+ 513 | Dosage | Drug | Patient | Date | 514 | +--------+ +-----------+ + 515 | 25 Indocin David 0001-01-01 12:00:12 AM 516 | 50 Enebrel Sam 0001-01-01 12:00:12 AM 517 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM 518 | 21 Combivent Janet 0001-01-01 12:00:12 AM 519 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM 520 | " 521 | 522 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 523 | } 524 | 525 | [Fact] 526 | public void TestColumnNameAlignment() 527 | { 528 | var table = TestUtilities.CreateTypicalTable(); 529 | 530 | Assert.Equal(TextAlignment.Center, table.Columns[1].GetColumnNameAlignment()); 531 | Assert.Equal( 532 | @" 533 | +-----------------------------------------------------------+ 534 | | Prescriptions | 535 | +--------+-------------+-----------+------------------------+ 536 | | Dosage | Drug | Patient | Date | 537 | +--------+-------------+-----------+------------------------+ 538 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 539 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 540 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 541 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 542 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 543 | +--------+-------------+-----------+------------------------+" 544 | 545 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 546 | 547 | table.Columns[1].SetColumnNameAlignment(TextAlignment.Left); 548 | Assert.Equal(TextAlignment.Left, table.Columns[1].GetColumnNameAlignment()); 549 | Assert.Equal( 550 | @" 551 | +-----------------------------------------------------------+ 552 | | Prescriptions | 553 | +--------+-------------+-----------+------------------------+ 554 | | Dosage | Drug | Patient | Date | 555 | +--------+-------------+-----------+------------------------+ 556 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 557 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 558 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 559 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 560 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 561 | +--------+-------------+-----------+------------------------+" 562 | 563 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 564 | 565 | table.Columns[1].SetColumnNameAlignment(TextAlignment.Right); 566 | Assert.Equal(TextAlignment.Right, table.Columns[1].GetColumnNameAlignment()); 567 | Assert.Equal( 568 | @" 569 | +-----------------------------------------------------------+ 570 | | Prescriptions | 571 | +--------+-------------+-----------+------------------------+ 572 | | Dosage | Drug | Patient | Date | 573 | +--------+-------------+-----------+------------------------+ 574 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 575 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 576 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 577 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 578 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 579 | +--------+-------------+-----------+------------------------+" 580 | 581 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 582 | } 583 | 584 | [Fact] 585 | public void TestShowColumnName() 586 | { 587 | var table = TestUtilities.CreateTypicalTable(); 588 | 589 | Assert.True(table.Columns[0].GetShowColumnName()); 590 | 591 | table.Columns[0].SetShowColumnName(false); 592 | Assert.False(table.Columns[0].GetShowColumnName()); 593 | Assert.Equal( 594 | @" 595 | +--------------------------------------------------------+ 596 | | Prescriptions | 597 | +-----+-------------+-----------+------------------------+ 598 | | | Drug | Patient | Date | 599 | +-----+-------------+-----------+------------------------+ 600 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 601 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 602 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 603 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 604 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 605 | +-----+-------------+-----------+------------------------+" 606 | 607 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 608 | 609 | table.Columns[0].SetShowColumnName(false); 610 | table.Columns[2].SetShowColumnName(false); 611 | Assert.False(table.Columns[0].GetShowColumnName()); 612 | Assert.False(table.Columns[2].GetShowColumnName()); 613 | Assert.Equal( 614 | @" 615 | +--------------------------------------------------------+ 616 | | Prescriptions | 617 | +-----+-------------+-----------+------------------------+ 618 | | | Drug | | Date | 619 | +-----+-------------+-----------+------------------------+ 620 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 621 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 622 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 623 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 624 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 625 | +-----+-------------+-----------+------------------------+" 626 | 627 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 628 | } 629 | 630 | [Fact] 631 | public void TestWidth() 632 | { 633 | var table = TestUtilities.CreateTypicalTable(); 634 | 635 | Assert.Equal(8, table.Columns[0].GetWidth()); 636 | 637 | table.Columns[0].SetWidth(15); 638 | Assert.Equal(15, table.Columns[0].GetWidth()); 639 | Assert.Equal( 640 | @" 641 | +------------------------------------------------------------------+ 642 | | Prescriptions | 643 | +---------------+-------------+-----------+------------------------+ 644 | | Dosage | Drug | Patient | Date | 645 | +---------------+-------------+-----------+------------------------+ 646 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 647 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 648 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 649 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 650 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 651 | +---------------+-------------+-----------+------------------------+" 652 | 653 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 654 | 655 | table.Columns[0].SetWidth(2); 656 | Assert.Equal(2, table.Columns[0].GetWidth()); 657 | Assert.Equal( 658 | @" 659 | +-----------------------------------------------------+ 660 | | Prescriptions | 661 | +--+-------------+-----------+------------------------+ 662 | | | Drug | Patient | Date | 663 | +--+-------------+-----------+------------------------+ 664 | | | Indocin | David | 0001-01-01 12:00:12 AM | 665 | | | Enebrel | Sam | 0001-01-01 12:00:12 AM | 666 | | | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 667 | | | Combivent | Janet | 0001-01-01 12:00:12 AM | 668 | | | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 669 | +--+-------------+-----------+------------------------+" 670 | 671 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 672 | 673 | table.Columns[0].SetWidth(4); 674 | Assert.Equal(4, table.Columns[0].GetWidth()); 675 | Assert.Equal( 676 | @" 677 | +-------------------------------------------------------+ 678 | | Prescriptions | 679 | +----+-------------+-----------+------------------------+ 680 | | .. | Drug | Patient | Date | 681 | +----+-------------+-----------+------------------------+ 682 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 683 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 684 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 685 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 686 | | .. | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 687 | +----+-------------+-----------+------------------------+" 688 | 689 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 690 | 691 | table.Columns[0].SetWidth(5); 692 | Assert.Equal(5, table.Columns[0].GetWidth()); 693 | Assert.Equal( 694 | @" 695 | +--------------------------------------------------------+ 696 | | Prescriptions | 697 | +-----+-------------+-----------+------------------------+ 698 | | D.. | Drug | Patient | Date | 699 | +-----+-------------+-----------+------------------------+ 700 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 701 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 702 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 703 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 704 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 705 | +-----+-------------+-----------+------------------------+" 706 | 707 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 708 | 709 | table.Columns[0].SetWidth(5); 710 | table.Columns[1].SetWidth(5); 711 | table.Columns[2].SetWidth(5); 712 | table.Columns[3].SetWidth(5); 713 | Assert.Equal(5, table.Columns[0].GetWidth()); 714 | Assert.Equal(5, table.Columns[1].GetWidth()); 715 | Assert.Equal(5, table.Columns[2].GetWidth()); 716 | Assert.Equal(5, table.Columns[3].GetWidth()); 717 | Assert.Equal( 718 | @" 719 | +-----------------------+ 720 | | Prescriptions | 721 | +-----+-----+-----+-----+ 722 | | D.. | D.. | P.. | D.. | 723 | +-----+-----+-----+-----+ 724 | | 25 | I.. | D.. | 0.. | 725 | | 50 | E.. | Sam | 0.. | 726 | | 10 | H.. | C.. | 0.. | 727 | | 21 | C.. | J.. | 0.. | 728 | | 100 | D.. | M.. | 0.. | 729 | +-----+-----+-----+-----+" 730 | 731 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 732 | 733 | table.Columns[0].SetWidth(2); 734 | table.Columns[1].SetWidth(2); 735 | table.Columns[2].SetWidth(2); 736 | table.Columns[3].SetWidth(2); 737 | Assert.Equal(2, table.Columns[0].GetWidth()); 738 | Assert.Equal(2, table.Columns[1].GetWidth()); 739 | Assert.Equal(2, table.Columns[2].GetWidth()); 740 | Assert.Equal(2, table.Columns[3].GetWidth()); 741 | Assert.Equal( 742 | @" 743 | +-----------+ 744 | | Prescri.. | 745 | +--+--+--+--+ 746 | | | | | | 747 | +--+--+--+--+ 748 | | | | | | 749 | | | | | | 750 | | | | | | 751 | | | | | | 752 | | | | | | 753 | +--+--+--+--+" 754 | 755 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 756 | 757 | table.Columns[0].SetWidth(0); 758 | table.Columns[1].SetWidth(0); 759 | table.Columns[2].SetWidth(0); 760 | table.Columns[3].SetWidth(0); 761 | Assert.Equal(1, table.Columns[0].GetWidth()); 762 | Assert.Equal(1, table.Columns[1].GetWidth()); 763 | Assert.Equal(1, table.Columns[2].GetWidth()); 764 | Assert.Equal(1, table.Columns[3].GetWidth()); 765 | Assert.Equal( 766 | @" 767 | +-------+ 768 | | Pre.. | 769 | +-+-+-+-+ 770 | | | | | | 771 | +-+-+-+-+ 772 | | | | | | 773 | | | | | | 774 | | | | | | 775 | | | | | | 776 | | | | | | 777 | +-+-+-+-+" 778 | 779 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 780 | } 781 | } 782 | } 783 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter.Tests/TestDataTableExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter.Tests 2 | { 3 | using Xunit; 4 | 5 | public class TestDataTableExtensions 6 | { 7 | [Fact] 8 | public void TestBorder() 9 | { 10 | var table = TestUtilities.CreateTypicalTable(); 11 | 12 | Assert.Equal(Border.All, table.GetBorder()); 13 | Assert.Equal( 14 | @" 15 | +-----------------------------------------------------------+ 16 | | Prescriptions | 17 | +--------+-------------+-----------+------------------------+ 18 | | Dosage | Drug | Patient | Date | 19 | +--------+-------------+-----------+------------------------+ 20 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 21 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 22 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 23 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 24 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 25 | +--------+-------------+-----------+------------------------+" 26 | 27 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 28 | 29 | table.SetBorder(Border.Left | Border.Top | Border.Right | Border.Bottom); 30 | Assert.Equal(Border.All, table.GetBorder()); 31 | 32 | table.SetBorder(Border.None); 33 | Assert.Equal(Border.None, table.GetBorder()); 34 | Assert.Equal( 35 | @" 36 | 37 | Prescriptions 38 | +--------+-------------+-----------+------------------------+ 39 | | Dosage | Drug | Patient | Date | 40 | +--------+-------------+-----------+------------------------+ 41 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 42 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 43 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 44 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 45 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 46 | +--------+-------------+-----------+------------------------+" 47 | 48 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 49 | 50 | table.SetBorder(Border.Left); 51 | Assert.Equal(Border.Left, table.GetBorder()); 52 | Assert.Equal( 53 | @" 54 | + 55 | | Prescriptions 56 | +--------+-------------+-----------+------------------------+ 57 | | Dosage | Drug | Patient | Date | 58 | +--------+-------------+-----------+------------------------+ 59 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 60 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 61 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 62 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 63 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 64 | +--------+-------------+-----------+------------------------+" 65 | 66 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 67 | 68 | table.SetBorder(Border.Right); 69 | Assert.Equal(Border.Right, table.GetBorder()); 70 | Assert.Equal( 71 | @" 72 | + 73 | Prescriptions | 74 | +--------+-------------+-----------+------------------------+ 75 | | Dosage | Drug | Patient | Date | 76 | +--------+-------------+-----------+------------------------+ 77 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 78 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 79 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 80 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 81 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 82 | +--------+-------------+-----------+------------------------+" 83 | 84 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 85 | 86 | table.SetBorder(Border.Top); 87 | Assert.Equal(Border.Top, table.GetBorder()); 88 | Assert.Equal( 89 | @" 90 | +-----------------------------------------------------------+ 91 | Prescriptions 92 | +--------+-------------+-----------+------------------------+ 93 | | Dosage | Drug | Patient | Date | 94 | +--------+-------------+-----------+------------------------+ 95 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 96 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 97 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 98 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 99 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 100 | +--------+-------------+-----------+------------------------+" 101 | 102 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 103 | 104 | table.SetBorder(Border.Bottom); 105 | Assert.Equal(Border.Bottom, table.GetBorder()); 106 | Assert.Equal( 107 | @" 108 | 109 | Prescriptions 110 | +--------+-------------+-----------+------------------------+ 111 | | Dosage | Drug | Patient | Date | 112 | +--------+-------------+-----------+------------------------+ 113 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 114 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 115 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 116 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 117 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 118 | +--------+-------------+-----------+------------------------+" 119 | 120 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 121 | 122 | table.SetBorder(Border.Top | Border.Right); 123 | Assert.Equal(Border.Top | Border.Right, table.GetBorder()); 124 | Assert.Equal( 125 | @" 126 | +-----------------------------------------------------------+ 127 | Prescriptions | 128 | +--------+-------------+-----------+------------------------+ 129 | | Dosage | Drug | Patient | Date | 130 | +--------+-------------+-----------+------------------------+ 131 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 132 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 133 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 134 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 135 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 136 | +--------+-------------+-----------+------------------------+" 137 | 138 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 139 | } 140 | 141 | [Fact] 142 | public void TestBorderOnTypicalTableWithoutBorders() 143 | { 144 | var table = TestUtilities.CreateTypicalTableWithoutBorders(); 145 | 146 | Assert.Equal(Border.None, table.GetBorder()); 147 | Assert.Equal( 148 | @" 149 | 150 | Prescriptions 151 | 152 | Dosage Drug Patient Date 153 | 154 | 25 Indocin David 0001-01-01 12:00:12 AM 155 | 50 Enebrel Sam 0001-01-01 12:00:12 AM 156 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM 157 | 21 Combivent Janet 0001-01-01 12:00:12 AM 158 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM 159 | " 160 | 161 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 162 | 163 | table.SetBorder(Border.Left | Border.Top | Border.Right | Border.Bottom); 164 | Assert.Equal(Border.All, table.GetBorder()); 165 | Assert.Equal( 166 | @" 167 | +-----------------------------------------------------------+ 168 | | Prescriptions | 169 | | | 170 | | Dosage Drug Patient Date | 171 | | | 172 | | 25 Indocin David 0001-01-01 12:00:12 AM | 173 | | 50 Enebrel Sam 0001-01-01 12:00:12 AM | 174 | | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM | 175 | | 21 Combivent Janet 0001-01-01 12:00:12 AM | 176 | | 100 Dilantin Melanie 0001-01-01 12:00:12 AM | 177 | +-----------------------------------------------------------+" 178 | 179 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 180 | 181 | table.SetBorder(Border.Left); 182 | Assert.Equal(Border.Left, table.GetBorder()); 183 | Assert.Equal( 184 | @" 185 | + 186 | | Prescriptions 187 | | 188 | | Dosage Drug Patient Date 189 | | 190 | | 25 Indocin David 0001-01-01 12:00:12 AM 191 | | 50 Enebrel Sam 0001-01-01 12:00:12 AM 192 | | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM 193 | | 21 Combivent Janet 0001-01-01 12:00:12 AM 194 | | 100 Dilantin Melanie 0001-01-01 12:00:12 AM 195 | + " 196 | 197 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 198 | 199 | table.SetBorder(Border.Right); 200 | Assert.Equal(Border.Right, table.GetBorder()); 201 | Assert.Equal( 202 | @" 203 | + 204 | Prescriptions | 205 | | 206 | Dosage Drug Patient Date | 207 | | 208 | 25 Indocin David 0001-01-01 12:00:12 AM | 209 | 50 Enebrel Sam 0001-01-01 12:00:12 AM | 210 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM | 211 | 21 Combivent Janet 0001-01-01 12:00:12 AM | 212 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM | 213 | +" 214 | 215 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 216 | 217 | table.SetBorder(Border.Left | Border.Right); 218 | Assert.Equal(Border.Left | Border.Right, table.GetBorder()); 219 | Assert.Equal( 220 | @" 221 | + + 222 | | Prescriptions | 223 | | | 224 | | Dosage Drug Patient Date | 225 | | | 226 | | 25 Indocin David 0001-01-01 12:00:12 AM | 227 | | 50 Enebrel Sam 0001-01-01 12:00:12 AM | 228 | | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM | 229 | | 21 Combivent Janet 0001-01-01 12:00:12 AM | 230 | | 100 Dilantin Melanie 0001-01-01 12:00:12 AM | 231 | + +" 232 | 233 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 234 | 235 | table.SetBorder(Border.Top | Border.Right | Border.Bottom); 236 | Assert.Equal(Border.Top | Border.Right | Border.Bottom, table.GetBorder()); 237 | Assert.Equal( 238 | @" 239 | +-----------------------------------------------------------+ 240 | Prescriptions | 241 | | 242 | Dosage Drug Patient Date | 243 | | 244 | 25 Indocin David 0001-01-01 12:00:12 AM | 245 | 50 Enebrel Sam 0001-01-01 12:00:12 AM | 246 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM | 247 | 21 Combivent Janet 0001-01-01 12:00:12 AM | 248 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM | 249 | +-----------------------------------------------------------+" 250 | 251 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 252 | 253 | table.SetBorder(Border.Top | Border.Right); 254 | Assert.Equal(Border.Top | Border.Right, table.GetBorder()); 255 | Assert.Equal( 256 | @" 257 | +-----------------------------------------------------------+ 258 | Prescriptions | 259 | | 260 | Dosage Drug Patient Date | 261 | | 262 | 25 Indocin David 0001-01-01 12:00:12 AM | 263 | 50 Enebrel Sam 0001-01-01 12:00:12 AM | 264 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM | 265 | 21 Combivent Janet 0001-01-01 12:00:12 AM | 266 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM | 267 | +" 268 | 269 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 270 | 271 | table.SetBorder(Border.Bottom); 272 | Assert.Equal(Border.Bottom, table.GetBorder()); 273 | Assert.Equal( 274 | @" 275 | 276 | Prescriptions 277 | 278 | Dosage Drug Patient Date 279 | 280 | 25 Indocin David 0001-01-01 12:00:12 AM 281 | 50 Enebrel Sam 0001-01-01 12:00:12 AM 282 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM 283 | 21 Combivent Janet 0001-01-01 12:00:12 AM 284 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM 285 | +-----------------------------------------------------------+" 286 | 287 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 288 | 289 | table.SetShowTableName(false); 290 | table.SetShowColumnHeader(false); 291 | table.SetBorder(Border.Top | Border.Right | Border.Bottom); 292 | Assert.Equal(Border.Top | Border.Right | Border.Bottom, table.GetBorder()); 293 | Assert.Equal( 294 | @" 295 | +-----------------------------------------------------------+ 296 | 25 Indocin David 0001-01-01 12:00:12 AM | 297 | 50 Enebrel Sam 0001-01-01 12:00:12 AM | 298 | 10 Hydralazine Christoff 0001-01-01 12:00:12 AM | 299 | 21 Combivent Janet 0001-01-01 12:00:12 AM | 300 | 100 Dilantin Melanie 0001-01-01 12:00:12 AM | 301 | +-----------------------------------------------------------+" 302 | 303 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 304 | } 305 | 306 | [Fact] 307 | public void TestShowColumnHeader() 308 | { 309 | var table = TestUtilities.CreateTypicalTable(); 310 | 311 | Assert.True(table.GetShowColumnHeader()); 312 | Assert.Equal( 313 | @" 314 | +-----------------------------------------------------------+ 315 | | Prescriptions | 316 | +--------+-------------+-----------+------------------------+ 317 | | Dosage | Drug | Patient | Date | 318 | +--------+-------------+-----------+------------------------+ 319 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 320 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 321 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 322 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 323 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 324 | +--------+-------------+-----------+------------------------+" 325 | 326 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 327 | 328 | table.SetShowColumnHeader(false); 329 | Assert.False(table.GetShowColumnHeader()); 330 | Assert.Equal( 331 | @" 332 | +-----------------------------------------------------------+ 333 | | Prescriptions | 334 | +--------+-------------+-----------+------------------------+ 335 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 336 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 337 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 338 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 339 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 340 | +--------+-------------+-----------+------------------------+" 341 | 342 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 343 | 344 | table.SetShowTableName(false); 345 | Assert.False(table.GetShowTableName()); 346 | Assert.Equal( 347 | @" 348 | +--------+-------------+-----------+------------------------+ 349 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 350 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 351 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 352 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 353 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 354 | +--------+-------------+-----------+------------------------+" 355 | 356 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 357 | 358 | table.SetShowColumnHeader(true); 359 | Assert.True(table.GetShowColumnHeader()); 360 | Assert.Equal( 361 | @" 362 | +--------+-------------+-----------+------------------------+ 363 | | Dosage | Drug | Patient | Date | 364 | +--------+-------------+-----------+------------------------+ 365 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 366 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 367 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 368 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 369 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 370 | +--------+-------------+-----------+------------------------+" 371 | 372 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 373 | } 374 | 375 | [Fact] 376 | public void TestShowTableName() 377 | { 378 | var table = TestUtilities.CreateTypicalTable(); 379 | 380 | Assert.True(table.GetShowTableName()); 381 | Assert.Equal( 382 | @" 383 | +-----------------------------------------------------------+ 384 | | Prescriptions | 385 | +--------+-------------+-----------+------------------------+ 386 | | Dosage | Drug | Patient | Date | 387 | +--------+-------------+-----------+------------------------+ 388 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 389 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 390 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 391 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 392 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 393 | +--------+-------------+-----------+------------------------+" 394 | 395 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 396 | 397 | table.SetShowTableName(false); 398 | Assert.False(table.GetShowTableName()); 399 | Assert.Equal( 400 | @" 401 | +--------+-------------+-----------+------------------------+ 402 | | Dosage | Drug | Patient | Date | 403 | +--------+-------------+-----------+------------------------+ 404 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 405 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 406 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 407 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 408 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 409 | +--------+-------------+-----------+------------------------+" 410 | 411 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 412 | 413 | table.TableName = "A really long table name that will not fit in the title bounding box"; 414 | table.SetShowTableName(true); 415 | Assert.True(table.GetShowTableName()); 416 | Assert.Equal( 417 | @" 418 | +-----------------------------------------------------------+ 419 | | A really long table name that will not fit in the title.. | 420 | +--------+-------------+-----------+------------------------+ 421 | | Dosage | Drug | Patient | Date | 422 | +--------+-------------+-----------+------------------------+ 423 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 424 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 425 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 426 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 427 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 428 | +--------+-------------+-----------+------------------------+" 429 | 430 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 431 | } 432 | 433 | [Fact] 434 | public void TestShowTableNameOnSkinnyTable() 435 | { 436 | var table = TestUtilities.CreateSkinnyTable(); 437 | 438 | Assert.True(table.GetShowTableName()); 439 | Assert.Equal( 440 | @" 441 | +---+ 442 | | | 443 | +---+ 444 | | A | 445 | +---+ 446 | | | 447 | | | 448 | | | 449 | | | 450 | | | 451 | | | 452 | | | 453 | | | 454 | | | 455 | +---+" 456 | 457 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 458 | 459 | table.SetShowTableName(false); 460 | Assert.False(table.GetShowTableName()); 461 | Assert.Equal( 462 | @" 463 | +---+ 464 | | A | 465 | +---+ 466 | | | 467 | | | 468 | | | 469 | | | 470 | | | 471 | | | 472 | | | 473 | | | 474 | | | 475 | +---+" 476 | 477 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 478 | 479 | table.TableName = "T"; 480 | table.SetShowTableName(true); 481 | Assert.True(table.GetShowTableName()); 482 | Assert.Equal( 483 | @" 484 | +---+ 485 | | T | 486 | +---+ 487 | | A | 488 | +---+ 489 | | | 490 | | | 491 | | | 492 | | | 493 | | | 494 | | | 495 | | | 496 | | | 497 | | | 498 | +---+" 499 | 500 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 501 | 502 | table.TableName = "Table name that doesn't fit"; 503 | table.SetShowTableName(true); 504 | Assert.True(table.GetShowTableName()); 505 | Assert.Equal( 506 | @" 507 | +---+ 508 | | | 509 | +---+ 510 | | A | 511 | +---+ 512 | | | 513 | | | 514 | | | 515 | | | 516 | | | 517 | | | 518 | | | 519 | | | 520 | | | 521 | +---+" 522 | 523 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 524 | } 525 | 526 | [Fact] 527 | public void TestTitleTextAlignment() 528 | { 529 | var table = TestUtilities.CreateTypicalTable(); 530 | 531 | Assert.Equal(TextAlignment.Center, table.GetTitleTextAlignment()); 532 | Assert.Equal( 533 | @" 534 | +-----------------------------------------------------------+ 535 | | Prescriptions | 536 | +--------+-------------+-----------+------------------------+ 537 | | Dosage | Drug | Patient | Date | 538 | +--------+-------------+-----------+------------------------+ 539 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 540 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 541 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 542 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 543 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 544 | +--------+-------------+-----------+------------------------+" 545 | 546 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 547 | 548 | table.SetTitleTextAlignment(TextAlignment.Left); 549 | Assert.Equal(TextAlignment.Left, table.GetTitleTextAlignment()); 550 | Assert.Equal( 551 | @" 552 | +-----------------------------------------------------------+ 553 | | Prescriptions | 554 | +--------+-------------+-----------+------------------------+ 555 | | Dosage | Drug | Patient | Date | 556 | +--------+-------------+-----------+------------------------+ 557 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 558 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 559 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 560 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 561 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 562 | +--------+-------------+-----------+------------------------+" 563 | 564 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 565 | 566 | table.SetTitleTextAlignment(TextAlignment.Right); 567 | Assert.Equal(TextAlignment.Right, table.GetTitleTextAlignment()); 568 | Assert.Equal( 569 | @" 570 | +-----------------------------------------------------------+ 571 | | Prescriptions | 572 | +--------+-------------+-----------+------------------------+ 573 | | Dosage | Drug | Patient | Date | 574 | +--------+-------------+-----------+------------------------+ 575 | | 25 | Indocin | David | 0001-01-01 12:00:12 AM | 576 | | 50 | Enebrel | Sam | 0001-01-01 12:00:12 AM | 577 | | 10 | Hydralazine | Christoff | 0001-01-01 12:00:12 AM | 578 | | 21 | Combivent | Janet | 0001-01-01 12:00:12 AM | 579 | | 100 | Dilantin | Melanie | 0001-01-01 12:00:12 AM | 580 | +--------+-------------+-----------+------------------------+" 581 | 582 | .TrimLeadingWhitespace(), table.ToPrettyPrintedString().TrimLeadingWhitespace()); 583 | } 584 | } 585 | } 586 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter.Tests/TestUtilities.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter.Tests 2 | { 3 | using System; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | internal static class TestUtilities 9 | { 10 | internal static string TrimLeadingWhitespace(this string value) 11 | { 12 | var sb = new StringBuilder(); 13 | 14 | foreach (string line in value.Split(new[] { Environment.NewLine }, StringSplitOptions.None)) 15 | { 16 | string trimmed = line.Trim(); 17 | 18 | if (!string.IsNullOrWhiteSpace(trimmed)) 19 | { 20 | sb.AppendLine(trimmed); 21 | } 22 | } 23 | 24 | return sb.ToString(); 25 | } 26 | 27 | internal static DataTable CreateTypicalTable() 28 | { 29 | DataTable table = new DataTable("Prescriptions"); 30 | 31 | table.Columns.Add("Dosage", typeof(int)); 32 | table.Columns.Add("Drug", typeof(string)); 33 | table.Columns.Add("Patient", typeof(string)); 34 | table.Columns.Add("Date", typeof(string)); 35 | 36 | table.Rows.Add(25, "Indocin", "David", "0001-01-01 12:00:12 AM"); 37 | table.Rows.Add(50, "Enebrel", "Sam", "0001-01-01 12:00:12 AM"); 38 | table.Rows.Add(10, "Hydralazine", "Christoff", "0001-01-01 12:00:12 AM"); 39 | table.Rows.Add(21, "Combivent", "Janet", "0001-01-01 12:00:12 AM"); 40 | table.Rows.Add(100, "Dilantin", "Melanie", "0001-01-01 12:00:12 AM"); 41 | 42 | return table; 43 | } 44 | 45 | internal static DataTable CreateTypicalTableWithoutBorders() 46 | { 47 | DataTable table = CreateTypicalTable(); 48 | 49 | table.SetBorder(Border.None); 50 | 51 | table.Columns.Cast().AsParallel().ForAll(c => c.SetDataBorder(Border.None)); 52 | table.Columns.Cast().AsParallel().ForAll(c => c.SetHeaderBorder(Border.None)); 53 | 54 | return table; 55 | } 56 | 57 | internal static DataTable CreateSkinnyTable() 58 | { 59 | DataTable table = new DataTable(); 60 | 61 | table.Columns.Add("A", typeof(string)); 62 | 63 | table.Rows.Add(string.Empty); 64 | table.Rows.Add(string.Empty); 65 | table.Rows.Add(string.Empty); 66 | table.Rows.Add(string.Empty); 67 | table.Rows.Add(string.Empty); 68 | table.Rows.Add(string.Empty); 69 | table.Rows.Add(string.Empty); 70 | table.Rows.Add(string.Empty); 71 | table.Rows.Add(string.Empty); 72 | 73 | return table; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29609.76 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataTablePrettyPrinter", "DataTablePrettyPrinter\DataTablePrettyPrinter.csproj", "{7D7535B5-D0D1-4B97-AB65-2B504CF10F8C}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataTablePrettyPrinter.Tests", "DataTablePrettyPrinter.Tests\DataTablePrettyPrinter.Tests.csproj", "{AEE312CB-1893-4976-BB61-E72A90C708E2}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {7D7535B5-D0D1-4B97-AB65-2B504CF10F8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {7D7535B5-D0D1-4B97-AB65-2B504CF10F8C}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {7D7535B5-D0D1-4B97-AB65-2B504CF10F8C}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {7D7535B5-D0D1-4B97-AB65-2B504CF10F8C}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {AEE312CB-1893-4976-BB61-E72A90C708E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {AEE312CB-1893-4976-BB61-E72A90C708E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {AEE312CB-1893-4976-BB61-E72A90C708E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {AEE312CB-1893-4976-BB61-E72A90C708E2}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {EA62B77B-AFF3-47C0-A615-32E99A9A53AC} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/Border.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter 2 | { 3 | using System; 4 | using System.Data; 5 | 6 | /// 7 | /// Enumerates the border flags of the text represented by a which is to be drawn on a 8 | /// pretty printed string. 9 | /// 10 | [Flags] 11 | public enum Border 12 | { 13 | /// 14 | /// No border. 15 | /// 16 | None = 0, 17 | 18 | /// 19 | /// Bottom border. 20 | /// 21 | Bottom = 1, 22 | 23 | /// 24 | /// Left border. 25 | /// 26 | Left = 2, 27 | 28 | /// 29 | /// Right border. 30 | /// 31 | Right = 4, 32 | 33 | /// 34 | /// Top border. 35 | /// 36 | Top = 8, 37 | 38 | /// 39 | /// All borders. 40 | /// 41 | All = 15, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/CharExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter 2 | { 3 | using System; 4 | 5 | /// 6 | /// An extension class providing utility methods for pretty printing to a string. 7 | /// 8 | internal static class CharExtensions 9 | { 10 | /// 11 | /// Draws a border on a canvas given a bounding box specified by coordinates. 12 | /// 13 | /// 14 | /// 15 | /// The canvas to draw on which is assumed to be large enough. 16 | /// 17 | /// 18 | /// 19 | /// The x coordinate of the beginning of the bounding box to draw. 20 | /// 21 | /// 22 | /// 23 | /// The y coordinate of the beginning of the bounding box to draw. 24 | /// 25 | /// 26 | /// 27 | /// The x coordinate of the end of the bounding box to draw. 28 | /// 29 | /// 30 | /// 31 | /// The y coordinate of the end of the bounding box to draw. 32 | /// 33 | /// 34 | /// 35 | /// The border flags which dictate which border to draw. 36 | /// 37 | internal static void DrawBorder(this char[,] canvas, int x1, int y1, int x2, int y2, Border border) 38 | { 39 | if (border.HasFlag(Border.Top)) 40 | { 41 | canvas.DrawLine(x1, y1, x2, y1); 42 | } 43 | 44 | if (border.HasFlag(Border.Bottom)) 45 | { 46 | canvas.DrawLine(x1, y2, x2, y2); 47 | } 48 | 49 | if (border.HasFlag(Border.Left)) 50 | { 51 | canvas.DrawLine(x1, y1, x1, y2); 52 | } 53 | 54 | if (border.HasFlag(Border.Right)) 55 | { 56 | canvas.DrawLine(x2, y1, x2, y2); 57 | } 58 | } 59 | 60 | /// 61 | /// Draws a line on a canvas given a beginning and an end coordinate. 62 | /// 63 | /// 64 | /// 65 | /// The canvas to draw on which is assumed to be large enough. 66 | /// 67 | /// 68 | /// 69 | /// The x coordinate of the beginning of the line to draw. 70 | /// 71 | /// 72 | /// 73 | /// The y coordinate of the beginning of the line to draw. 74 | /// 75 | /// 76 | /// 77 | /// The x coordinate of the end of the line to draw. 78 | /// 79 | /// 80 | /// 81 | /// The y coordinate of the end of the line to draw. 82 | /// 83 | /// 84 | /// 85 | /// If this line crosses any other line drawn on the canvas then a '+' is inserted on the crossing boundary. 86 | /// 87 | /// 88 | /// 89 | /// Thrown when the line is neither horizontal nor vertical. 90 | /// 91 | internal static void DrawLine(this char[,] canvas, int x1, int y1, int x2, int y2) 92 | { 93 | if (x1 != x2 && y1 != y2) 94 | { 95 | throw new ArgumentException("Cannot draw non-horizontal or non-vertical lines"); 96 | } 97 | 98 | if (x1 == x2) 99 | { 100 | if (y1 > y2) 101 | { 102 | Utilities.Swap(ref y1, ref y2); 103 | } 104 | 105 | for (var y = y1; y <= y2; ++y) 106 | { 107 | canvas[y, x1] = (y == y1 || y == y2 || canvas[y, x1] == '-' || canvas[y, x1] == '+') ? '+' : '|'; 108 | } 109 | } 110 | else 111 | { 112 | if (x1 > x2) 113 | { 114 | Utilities.Swap(ref x1, ref x2); 115 | } 116 | 117 | for (var x = x1; x <= x2; ++x) 118 | { 119 | canvas[y1, x] = (x == x1 || x == x2 || canvas[y1, x] == '|' || canvas[y1, x] == '+') ? '+' : '-'; 120 | } 121 | } 122 | } 123 | 124 | /// 125 | /// Draws a string on a canvas with alignment specified. 126 | /// 127 | /// 128 | /// 129 | /// The canvas to draw on which is assumed to be large enough. 130 | /// 131 | /// 132 | /// 133 | /// The x coordinate of the beginning of the string to draw. 134 | /// 135 | /// 136 | /// 137 | /// The y coordinate of the beginning of the string to draw. 138 | /// 139 | /// 140 | /// 141 | /// The x coordinate of the end of the string to draw. 142 | /// 143 | /// 144 | /// 145 | /// The y coordinate of the end of the string to draw. 146 | /// 147 | /// 148 | /// 149 | /// The text to draw. 150 | /// 151 | /// 152 | /// 153 | /// The alignment of the to draw. 154 | /// 155 | /// 156 | /// 157 | /// If the text cannot be contained within the bounding box specified by the coordinates then either nothing is 158 | /// drawn or the input string is truncated and '..' is added to the end. 159 | /// 160 | internal static void DrawText(this char[,] canvas, int x1, int y1, int x2, int y2, string text, TextAlignment alignment) 161 | { 162 | // Truncate the text if it will not fit in the text box bounds 163 | if (text.Length > x2 - x1 + 1) 164 | { 165 | if (x2 - x1 >= 1) 166 | { 167 | text = text.Substring(0, x2 - x1 - 1) + ".."; 168 | } 169 | else 170 | { 171 | return; 172 | } 173 | } 174 | 175 | // Update the coordinates based the text alignment 176 | switch (alignment) 177 | { 178 | case TextAlignment.Center: 179 | { 180 | y1 = (y2 + y1) / 2; 181 | x1 += (x2 - x1 + 1 - text.Length) / 2; 182 | 183 | break; 184 | } 185 | 186 | case TextAlignment.Left: 187 | { 188 | y1 = (y2 + y1) / 2; 189 | 190 | break; 191 | } 192 | 193 | case TextAlignment.Right: 194 | { 195 | y1 = (y2 + y1) / 2; 196 | x1 = x2 - text.Length + 1; 197 | 198 | break; 199 | } 200 | 201 | default: 202 | { 203 | throw new InvalidOperationException("Unreachable case reached"); 204 | } 205 | } 206 | 207 | for (var x = x1; x < x1 + text.Length; ++x) 208 | { 209 | canvas[y1, x] = text[x - x1]; 210 | } 211 | } 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/DataColumnExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter 2 | { 3 | using System; 4 | using System.Data; 5 | using System.Linq; 6 | 7 | /// 8 | /// An extension class providing utility methods for pretty printing to a string. 9 | /// 10 | public static class DataColumnExtensions 11 | { 12 | /// 13 | /// Gets the border around the data area of the column. 14 | /// 15 | /// 16 | /// 17 | /// The column to pretty print. 18 | /// 19 | /// 20 | /// 21 | /// The border around the data area of the column. 22 | /// 23 | public static Border GetDataBorder(this DataColumn column) 24 | { 25 | return column.GetExtendedProperty("DataBorder", Border.All); 26 | } 27 | 28 | /// 29 | /// Sets the border around the data area of the column. 30 | /// 31 | /// 32 | /// 33 | /// The column to pretty print. 34 | /// 35 | /// 36 | /// 37 | /// The value to set. 38 | /// 39 | public static void SetDataBorder(this DataColumn column, Border value) 40 | { 41 | column.SetExtendedProperty("DataBorder", value); 42 | } 43 | 44 | /// 45 | /// Gets the text alignment of the data in this column. 46 | /// 47 | /// 48 | /// 49 | /// The column to pretty print. 50 | /// 51 | /// 52 | /// 53 | /// Gets the data alignment. 54 | /// 55 | public static TextAlignment GetDataAlignment(this DataColumn column) 56 | { 57 | return column.GetExtendedProperty("DataAlignment", TextAlignment.Left); 58 | } 59 | 60 | /// 61 | /// Sets the text alignment of the data in this column. 62 | /// 63 | /// 64 | /// 65 | /// The column to pretty print. 66 | /// 67 | /// 68 | /// 69 | /// The value to set. 70 | /// 71 | public static void SetDataAlignment(this DataColumn column, TextAlignment value) 72 | { 73 | column.SetExtendedProperty("DataAlignment", value); 74 | } 75 | 76 | /// 77 | /// Gets the formatting method which given a column and row formats the data of the cell into a string. This 78 | /// API can be used for arbitrary formatting of induvidual data cells. 79 | /// 80 | /// 81 | /// 82 | /// The column to pretty print. 83 | /// 84 | /// 85 | /// 86 | /// The method which formats the data cell. 87 | /// 88 | public static Func GetDataTextFormat(this DataColumn column) 89 | { 90 | return column.GetExtendedProperty>("DataTextFormat", (c, r) => string.Format("{0}", r[c])); 91 | } 92 | 93 | /// 94 | /// Sets the formatting method which given a column and row formats the data of the cell into a string. This 95 | /// API can be used for arbitrary formatting of induvidual data cells. 96 | /// 97 | /// 98 | /// 99 | /// The column to pretty print. 100 | /// 101 | /// 102 | /// 103 | /// The method used to format the data cell which will be called during pretty printing of the table. 104 | /// 105 | public static void SetDataTextFormat(this DataColumn column, Func value) 106 | { 107 | column.SetExtendedProperty("DataTextFormat", value); 108 | } 109 | 110 | /// 111 | /// Gets the border around the column header area which displays the column names. 112 | /// 113 | /// 114 | /// 115 | /// The column to pretty print. 116 | /// 117 | /// 118 | /// 119 | /// The border around the column header area. 120 | /// 121 | public static Border GetHeaderBorder(this DataColumn column) 122 | { 123 | return column.GetExtendedProperty("HeaderBorder", Border.All); 124 | } 125 | 126 | /// 127 | /// Sets the border around the column header area which displays the column names. 128 | /// 129 | /// 130 | /// 131 | /// The column to pretty print. 132 | /// 133 | /// 134 | /// 135 | /// The value to set. 136 | /// 137 | public static void SetHeaderBorder(this DataColumn column, Border value) 138 | { 139 | column.SetExtendedProperty("HeaderBorder", value); 140 | } 141 | 142 | /// 143 | /// Gets the text alignment. 144 | /// 145 | /// 146 | /// 147 | /// The column to pretty print. 148 | /// 149 | /// 150 | /// 151 | /// Gets the column name text alignment. 152 | /// 153 | public static TextAlignment GetColumnNameAlignment(this DataColumn column) 154 | { 155 | return column.GetExtendedProperty("ColumnNameAlignment", TextAlignment.Center); 156 | } 157 | 158 | /// 159 | /// Sets the text alignment. 160 | /// 161 | /// 162 | /// 163 | /// The column to pretty print. 164 | /// 165 | /// 166 | /// 167 | /// The value to set. 168 | /// 169 | public static void SetColumnNameAlignment(this DataColumn column, TextAlignment value) 170 | { 171 | column.SetExtendedProperty("ColumnNameAlignment", value); 172 | } 173 | 174 | /// 175 | /// Gets whether to show the . 176 | /// 177 | /// 178 | /// 179 | /// The column to pretty print. 180 | /// 181 | /// 182 | /// 183 | /// true if the column name is to be shown; false otherwise. 184 | /// 185 | public static bool GetShowColumnName(this DataColumn column) 186 | { 187 | return column.GetExtendedProperty("ShowColumnName", true); 188 | } 189 | 190 | /// 191 | /// Sets whether to show the . 192 | /// 193 | /// 194 | /// 195 | /// The column to pretty print. 196 | /// 197 | /// 198 | /// 199 | /// The value to set. 200 | /// 201 | public static void SetShowColumnName(this DataColumn column, bool value) 202 | { 203 | column.SetExtendedProperty("ShowColumnName", value); 204 | } 205 | 206 | /// 207 | /// Gets the width (in characters) of this column as it would appear on the pretty printed table. 208 | /// 209 | /// 210 | /// 211 | /// The input column. 212 | /// 213 | /// 214 | /// 215 | /// The width (in characters) of this column which is retrieved either by user defined value or the aggregate 216 | /// maximum width of any row in the table. 217 | /// 218 | public static int GetWidth(this DataColumn column) 219 | { 220 | if (column.ExtendedProperties.ContainsKey("Width")) 221 | { 222 | return (int)column.ExtendedProperties["Width"]; 223 | } 224 | else 225 | { 226 | var columnNameLength = 1; 227 | 228 | if (column.GetShowColumnName()) 229 | { 230 | columnNameLength = column.ColumnName.Length; 231 | } 232 | 233 | // Linq.Max cannot handle empty sequences 234 | if (column.Table.Rows.Count == 0) 235 | { 236 | return columnNameLength + 2; 237 | } 238 | else 239 | { 240 | return Math.Max(columnNameLength, column.Table.Rows.Cast().Max(r => column.GetDataTextFormat().Invoke(column, r).Length)) + 2; 241 | } 242 | } 243 | } 244 | 245 | /// 246 | /// Sets the width (in characters) of this column as it would appear on the pretty printed table. 247 | /// 248 | /// 249 | /// 250 | /// The input column. 251 | /// 252 | /// 253 | /// 254 | /// The value to set which will be clamped to be at least 1. 255 | /// 256 | public static void SetWidth(this DataColumn column, int value) 257 | { 258 | value = Math.Max(1, value); 259 | 260 | column.SetExtendedProperty("Width", value); 261 | } 262 | 263 | /// 264 | /// Gets the beginning X coordinate of the data area of this column. 265 | /// 266 | /// 267 | /// 268 | /// The input column. 269 | /// 270 | /// 271 | /// 272 | /// The X coordinate of the beginning of the data area. 273 | /// 274 | internal static int GetDataX1(this DataColumn column) 275 | { 276 | var columnIndex = column.Table.Columns.IndexOf(column); 277 | 278 | return column.Table.Columns.Cast().Take(columnIndex).Aggregate(0, (a, c) => a + c.GetWidth() + 1); 279 | } 280 | 281 | /// 282 | /// Gets the end X coordinate of the data area of this column. 283 | /// 284 | /// 285 | /// 286 | /// The input column. 287 | /// 288 | /// 289 | /// 290 | /// The X coordinate of the end of the data area. 291 | /// 292 | internal static int GetDataX2(this DataColumn column) 293 | { 294 | return column.GetDataX1() + 1 + column.GetWidth(); 295 | } 296 | 297 | /// 298 | /// Gets the beginning Y coordinate of the data area of this column. 299 | /// 300 | /// 301 | /// 302 | /// The input column. 303 | /// 304 | /// 305 | /// 306 | /// The Y coordinate of the beginning of the data area. 307 | /// 308 | internal static int GetDataY1(this DataColumn column) 309 | { 310 | // Account for the top border 311 | var y1 = 1; 312 | 313 | // Account for the title and a rule following the title 314 | if (column.Table.GetShowTableName()) 315 | { 316 | y1 += 2; 317 | } 318 | 319 | // Account for the header and a rule following the header 320 | if (column.Table.GetShowColumnHeader()) 321 | { 322 | y1 += 2; 323 | } 324 | 325 | return y1; 326 | } 327 | 328 | /// 329 | /// Gets the end Y coordinate of the data area of this column. 330 | /// 331 | /// 332 | /// 333 | /// The input column. 334 | /// 335 | /// 336 | /// 337 | /// The Y coordinate of the end of the data area. 338 | /// 339 | internal static int GetDataY2(this DataColumn column) 340 | { 341 | return column.GetDataY1() + column.Table.Rows.Cast().Aggregate(0, (a, r) => a + r.GetHeight()); 342 | } 343 | 344 | /// 345 | /// Gets an extended property from the with a default value if it does not exist. 346 | /// 347 | /// 348 | /// 349 | /// The type of the value to get. 350 | /// 351 | /// 352 | /// 353 | /// The column to pretty print. 354 | /// 355 | /// 356 | /// 357 | /// The extended property to get. 358 | /// 359 | /// 360 | /// 361 | /// The default value to return if the extended property does not exist. 362 | /// 363 | /// 364 | /// 365 | /// The value of the extended property if it exists; otherwise. 366 | /// 367 | internal static T GetExtendedProperty(this DataColumn column, string property, T defaultValue = default) 368 | { 369 | if (column.ExtendedProperties[property] is T) 370 | { 371 | return (T)column.ExtendedProperties[property]; 372 | } 373 | else 374 | { 375 | return defaultValue; 376 | } 377 | } 378 | 379 | /// 380 | /// Sets an extended property from the . 381 | /// 382 | /// 383 | /// 384 | /// The type of the value to get. 385 | /// 386 | /// 387 | /// 388 | /// The column to pretty print. 389 | /// 390 | /// 391 | /// 392 | /// The extended property to set. 393 | /// 394 | /// 395 | /// 396 | /// The value to set. 397 | /// 398 | internal static void SetExtendedProperty(this DataColumn column, string property, T value) 399 | { 400 | column.ExtendedProperties[property] = value; 401 | } 402 | } 403 | } 404 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/DataRowExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter 2 | { 3 | using System; 4 | using System.Data; 5 | using System.Linq; 6 | 7 | /// 8 | /// An extension class providing utility methods for pretty printing to a string. 9 | /// 10 | internal static class DataRowExtensions 11 | { 12 | /// 13 | /// Gets the width (in characters) of this row as it would appear on the pretty printed table by aggregating 14 | /// the widths of each individual column. 15 | /// 16 | /// 17 | /// 18 | /// The input row. 19 | /// 20 | /// 21 | /// 22 | /// The width (in characters) of this row. 23 | /// 24 | internal static int GetWidth(this DataRow row) 25 | { 26 | return row.Table.Columns.Cast().Aggregate(0, (a, c) => a + c.GetWidth() + 1) - 1; 27 | } 28 | 29 | /// 30 | /// Gets the height (in characters) of this row as it would appear on the pretty printed table by aggregating 31 | /// the heights of each individual column. 32 | /// 33 | /// 34 | /// 35 | /// The input row. 36 | /// 37 | /// 38 | /// 39 | /// The height (in characters) of this row. 40 | /// 41 | internal static int GetHeight(this DataRow row) 42 | { 43 | return 1; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/DataTableExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter 2 | { 3 | using System; 4 | using System.Data; 5 | using System.Linq; 6 | 7 | /// 8 | /// An extension class providing utility methods for pretty printing to a string. 9 | /// 10 | public static class DataTableExtensions 11 | { 12 | /// 13 | /// Gets the border around the entire table. 14 | /// 15 | /// 16 | /// 17 | /// The table to pretty print. 18 | /// 19 | /// 20 | /// 21 | /// The border around the entire table. 22 | /// 23 | public static Border GetBorder(this DataTable table) 24 | { 25 | return table.GetExtendedProperty("Border", Border.All); 26 | } 27 | 28 | /// 29 | /// Sets the border around the entire table. 30 | /// 31 | /// 32 | /// 33 | /// The table to pretty print. 34 | /// 35 | /// 36 | /// 37 | /// The value to set. 38 | /// 39 | public static void SetBorder(this DataTable table, Border value) 40 | { 41 | table.SetExtendedProperty("Border", value); 42 | } 43 | 44 | /// 45 | /// Gets whether to show the column header section which shows the column names. 46 | /// 47 | /// 48 | /// 49 | /// The table to pretty print. 50 | /// 51 | /// 52 | /// 53 | /// true if the column header is to be shown; false otherwise. 54 | /// 55 | public static bool GetShowColumnHeader(this DataTable table) 56 | { 57 | return table.GetExtendedProperty("ShowColumnHeader", true); 58 | } 59 | 60 | /// 61 | /// Sets whether to show the column header section which shows the column names. 62 | /// 63 | /// 64 | /// 65 | /// The table to pretty print. 66 | /// 67 | /// 68 | /// 69 | /// The value to set. 70 | /// 71 | public static void SetShowColumnHeader(this DataTable table, bool value) 72 | { 73 | table.SetExtendedProperty("ShowColumnHeader", value); 74 | } 75 | 76 | /// 77 | /// Gets whether to show the . 78 | /// 79 | /// 80 | /// 81 | /// The table to pretty print. 82 | /// 83 | /// 84 | /// 85 | /// true if the table title is to be shown; false otherwise. 86 | /// 87 | public static bool GetShowTableName(this DataTable table) 88 | { 89 | return table.GetExtendedProperty("ShowTableName", true); 90 | } 91 | 92 | /// 93 | /// Sets whether to show the . 94 | /// 95 | /// 96 | /// 97 | /// The table to pretty print. 98 | /// 99 | /// 100 | /// 101 | /// The value to set. 102 | /// 103 | public static void SetShowTableName(this DataTable table, bool value) 104 | { 105 | table.SetExtendedProperty("ShowTableName", value); 106 | } 107 | 108 | /// 109 | /// Gets the text alignment of the title determined by the property. 110 | /// 111 | /// 112 | /// 113 | /// The table to pretty print. 114 | /// 115 | /// 116 | /// 117 | /// Gets the title text alignment. 118 | /// 119 | public static TextAlignment GetTitleTextAlignment(this DataTable table) 120 | { 121 | return table.GetExtendedProperty("TitleTextAlignment", TextAlignment.Center); 122 | } 123 | 124 | /// 125 | /// Sets the text alignment of the title determined by the property. 126 | /// 127 | /// 128 | /// 129 | /// The table to pretty print. 130 | /// 131 | /// 132 | /// 133 | /// The value to set. 134 | /// 135 | public static void SetTitleTextAlignment(this DataTable table, TextAlignment value) 136 | { 137 | table.SetExtendedProperty("TitleTextAlignment", value); 138 | } 139 | 140 | /// 141 | /// Converts the into pretty printed string which can be displayed on the console. 142 | /// 143 | /// 144 | /// 145 | /// The table to pretty print. 146 | /// 147 | /// 148 | /// 149 | /// The pretty printed table. 150 | /// 151 | public static string ToPrettyPrintedString(this DataTable table) 152 | { 153 | int x2 = table.Columns.Cast().Last().GetDataX2(); 154 | int y2 = table.Columns.Cast().Last().GetDataY2(); 155 | 156 | char[] newLineChars = Environment.NewLine.ToCharArray(); 157 | char[,] canvas = new char[y2 + 1, x2 + 1 + newLineChars.Length]; 158 | 159 | // Fill the table with spaces and new lines at the end of each row 160 | for (var y = 0; y < y2 + 1; ++y) 161 | { 162 | for (var x = 0; x < x2 + 1; ++x) 163 | { 164 | canvas[y, x] = ' '; 165 | } 166 | 167 | for (var i = 0; i < newLineChars.Length; ++i) 168 | { 169 | canvas[y, x2 + 1 + i] = newLineChars[i]; 170 | } 171 | } 172 | 173 | // Draw the table border 174 | canvas.DrawBorder(0, 0, x2, y2, table.GetBorder()); 175 | 176 | // Keep track of the x and y coordinates we are drawing on 177 | int x1 = 0; 178 | int y1 = 0; 179 | 180 | if (table.GetShowTableName()) 181 | { 182 | ++y1; 183 | 184 | var titleAlignment = table.GetTitleTextAlignment(); 185 | canvas.DrawText(2, y1, x2 - 2, y1, table.TableName, titleAlignment); 186 | 187 | ++y1; 188 | } 189 | 190 | // Cache the column widths for performance 191 | var cachedColumnWidths = table.Columns.Cast().Select(c => c.GetWidth()).ToList(); 192 | 193 | if (table.GetShowColumnHeader()) 194 | { 195 | x1 = 0; 196 | 197 | for (var i = 0; i < table.Columns.Count; ++i) 198 | { 199 | // Draw the header border 200 | canvas.DrawBorder(x1, y1, x1 + cachedColumnWidths[i] + 1, y1 + 2, table.Columns[i].GetHeaderBorder()); 201 | 202 | if (table.Columns[i].GetShowColumnName()) 203 | { 204 | // Draw the header name 205 | canvas.DrawText(x1 + 2, y1 + 1, x1 + 1 + cachedColumnWidths[i] - 2, y1 + 1, table.Columns[i].ColumnName, table.Columns[i].GetColumnNameAlignment()); 206 | } 207 | 208 | x1 += cachedColumnWidths[i] + 1; 209 | } 210 | 211 | y1 += 2; 212 | } 213 | 214 | x1 = 0; 215 | 216 | for (var i = 0; i < table.Columns.Count; ++i) 217 | { 218 | // Draw the data border 219 | canvas.DrawBorder(x1, y1, x1 + cachedColumnWidths[i] + 1, y1 + table.Rows.Count + 1, table.Columns[i].GetDataBorder()); 220 | 221 | x1 += cachedColumnWidths[i] + 1; 222 | } 223 | 224 | ++y1; 225 | 226 | for (var i = 0; i < table.Rows.Count; ++i) 227 | { 228 | x1 = 2; 229 | 230 | for (var j = 0; j < table.Columns.Count; ++j) 231 | { 232 | var dataText = table.Columns[j].GetDataTextFormat().Invoke(table.Columns[j], table.Rows[i]); 233 | 234 | // Draw the cell text 235 | canvas.DrawText(x1, y1, x1 + cachedColumnWidths[j] - 3, y1, dataText, table.Columns[j].GetDataAlignment()); 236 | 237 | x1 += cachedColumnWidths[j] + 1; 238 | } 239 | 240 | ++y1; 241 | } 242 | 243 | var buffer = new char[canvas.GetLength(0) * canvas.GetLength(1)]; 244 | Buffer.BlockCopy(canvas, 0, buffer, 0, buffer.Length * sizeof(char)); 245 | 246 | return new string(buffer); 247 | } 248 | 249 | /// 250 | /// Gets an extended property from the with a default value if it does not exist. 251 | /// 252 | /// 253 | /// 254 | /// The type of the value to get. 255 | /// 256 | /// 257 | /// 258 | /// The table to pretty print. 259 | /// 260 | /// 261 | /// 262 | /// The extended property to get. 263 | /// 264 | /// 265 | /// 266 | /// The default value to return if the extended property does not exist. 267 | /// 268 | /// 269 | /// 270 | /// The value of the extended property if it exists; otherwise. 271 | /// 272 | internal static T GetExtendedProperty(this DataTable table, string property, T defaultValue = default) 273 | { 274 | if (table.ExtendedProperties[property] is T) 275 | { 276 | return (T)table.ExtendedProperties[property]; 277 | } 278 | else 279 | { 280 | return defaultValue; 281 | } 282 | } 283 | 284 | /// 285 | /// Sets an extended property from the . 286 | /// 287 | /// 288 | /// 289 | /// The type of the value to get. 290 | /// 291 | /// 292 | /// 293 | /// The table to pretty print. 294 | /// 295 | /// 296 | /// 297 | /// The extended property to set. 298 | /// 299 | /// 300 | /// 301 | /// The value to set. 302 | /// 303 | internal static void SetExtendedProperty(this DataTable table, string property, T value) 304 | { 305 | table.ExtendedProperties[property] = value; 306 | } 307 | } 308 | } 309 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/DataTablePrettyPrinter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | Filip Jeremic 6 | LICENSE 7 | An extension library of System.Data.DataTable which provides extension methods for fully customizable pretty-printing of DataTable to an ASCII formatted string which can be displayed on the console or any text buffer. 8 | https://github.com/fjeremic/DataTablePrettyPrinter 9 | https://github.com/fjeremic/DataTablePrettyPrinter 10 | GitHub 11 | DataTable;Print;PrettyPrint;Pretty-Print;Console;SQL 12 | 0.2.0 13 | Release notes: 14 | https://github.com/fjeremic/DataTablePrettyPrinter/releases 15 | true 16 | 17 | 18 | 19 | 20 | True 21 | 22 | 23 | 24 | 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers; buildtransitive 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header")] 9 | [assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:Prefix local calls with this")] 10 | [assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1404:Code analysis suppression should have justification")] 11 | [assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:Parameters should be on same line or separate lines")] 12 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/TextAlignment.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter 2 | { 3 | using System.Data; 4 | 5 | /// 6 | /// Enumerates the alignment of the text represented by a which is to be pretty printing to 7 | /// a string. 8 | /// 9 | public enum TextAlignment 10 | { 11 | /// 12 | /// Text is centered. 13 | /// 14 | Center, 15 | 16 | /// 17 | /// Text is aligned to the left. 18 | /// 19 | Left, 20 | 21 | /// 22 | /// Text is aligned to the right. 23 | /// 24 | Right, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DataTablePrettyPrinter/Utilities.cs: -------------------------------------------------------------------------------- 1 | namespace DataTablePrettyPrinter 2 | { 3 | /// 4 | /// A utility class with miscellaneous methods. 5 | /// 6 | internal static class Utilities 7 | { 8 | /// 9 | /// Swaps the values of and . 10 | /// 11 | /// 12 | /// 13 | /// The type of the values to swap. 14 | /// 15 | /// 16 | /// 17 | /// The value to swap with . 18 | /// 19 | /// 20 | /// 21 | /// The value to swap with . 22 | /// 23 | internal static void Swap(ref T x, ref T y) 24 | { 25 | T z = x; 26 | 27 | x = y; 28 | y = z; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Filip Jeremic 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DataTablePrettyPrinter 2 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/fjeremic/DataTablePrettyPrinter/blob/master/LICENSE) 3 | [![Build Status](https://dev.azure.com/fjeremic/DataTablePrettyPrinter/_apis/build/status/fjeremic.DataTablePrettyPrinter?branchName=master)](https://dev.azure.com/fjeremic/DataTablePrettyPrinter/_build/latest?definitionId=6&branchName=master) 4 | 5 | An extension library of System.Data.DataTable which provides extension methods for fully customizable pretty-printing of DataTables to an ASCII formatted string which can be displayed on the console or any text buffer. 6 | 7 | ## Installing / Getting started 8 | 9 | The best way to obtain the library is via the [DataTablePrettyPrinter NuGet package](https://www.nuget.org/packages/DataTablePrettyPrinter/): 10 | 11 | ```shell 12 | dotnet add package DataTablePrettyPrinter 13 | ``` 14 | 15 | Alternatively you may clone this git repository and build the library for use within your projects: 16 | 17 | ```shell 18 | dotnet build 19 | ``` 20 | 21 | ## Visual Overview 22 | 23 | The following mock table is an overview of the different areas of the `DataTable` which are displayed. The `TableName` and `ColumnName` values map directly onto their `DataTable.TableName` and `DataColumn.ColumnName` properties. The data area displays the row contents of the table. 24 | 25 | ``` 26 | +---------------------------------------------------+ 27 | | TableName | 28 | +------------+------------+------------+------------+ 29 | | ColumnName | ColumnName | ColumnName | ColumnName | 30 | +------------+------------+------------+------------+ 31 | | | | | | 32 | | | | | | 33 | | Data | Data | Data | Data | 34 | | Area | Area | Area | Area | 35 | | | | | | 36 | | | | | | 37 | +------------+------------+------------+------------+ 38 | ``` 39 | 40 | ## Examples 41 | 42 | To demonstrate the capabilities and ease of use of this library we will use a simple data table: 43 | 44 | ```csharp 45 | using DataTablePrettyPrinter; 46 | 47 | DataTable table = new DataTable("Prescriptions"); 48 | 49 | table.Columns.Add("Dosage", typeof(Int32)); 50 | table.Columns.Add("Drug", typeof(String)); 51 | table.Columns.Add("Patient", typeof(String)); 52 | table.Columns.Add("Date", typeof(DateTime)); 53 | 54 | table.Rows.Add(25, "Indocin", "David", DateTime.Parse("5/1/2008 12:30:52 PM")); 55 | table.Rows.Add(50, "Enebrel", "Sam", DateTime.Parse("9/11/2008 8:42:30 AM")); 56 | table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Parse("12/12/2019 9:15:00 AM")); 57 | table.Rows.Add(21, "Combivent", "Janet", DateTime.Parse("12/8/2018 3:00:00 PM")); 58 | table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Parse("9/14/2020 4:44:44 PM")); 59 | ``` 60 | 61 | ### Default pretty printing 62 | 63 | Default pretty printing is as easy as calling the `ToPrettyPrintedString` extension method: 64 | 65 | ```csharp 66 | Console.WriteLine(table.ToPrettyPrintedString()); 67 | ``` 68 | 69 | Output: 70 | 71 | ``` 72 | +-----------------------------------------------------------+ 73 | | Prescriptions | 74 | +--------+-------------+-----------+------------------------+ 75 | | Dosage | Drug | Patient | Date | 76 | +--------+-------------+-----------+------------------------+ 77 | | 25 | Indocin | David | 2008-05-01 12:30:52 PM | 78 | | 50 | Enebrel | Sam | 2008-09-11 8:42:30 AM | 79 | | 10 | Hydralazine | Christoff | 2019-12-12 9:15:00 AM | 80 | | 21 | Combivent | Janet | 2018-12-08 3:00:00 PM | 81 | | 100 | Dilantin | Melanie | 2020-09-14 4:44:44 PM | 82 | +--------+-------------+-----------+------------------------+ 83 | ``` 84 | 85 | ### Controlling borders 86 | 87 | Borders of the entire table or individual columns can be fully controlled. The library allows you to specify borders with a flags `enum`. We can for example disable drawing of side columns: 88 | 89 | 90 | ```csharp 91 | table.SetBorder(Border.Top | Border.Left); 92 | 93 | table.Columns[0].SetHeaderBorder(Border.Top); 94 | table.Columns[1].SetHeaderBorder(Border.Bottom | Border.Left); 95 | table.Columns[2].SetHeaderBorder(Border.Bottom | Border.Left); 96 | table.Columns[3].SetHeaderBorder(Border.Bottom | Border.Left); 97 | 98 | table.Columns[0].SetDataBorder(Border.None); 99 | table.Columns[1].SetDataBorder(Border.Left); 100 | table.Columns[2].SetDataBorder(Border.Left); 101 | table.Columns[3].SetDataBorder(Border.Left); 102 | 103 | Console.WriteLine(table.ToPrettyPrintedString()); 104 | ``` 105 | 106 | Output: 107 | 108 | ``` 109 | 110 | Prescriptions 111 | + + + 112 | Dosage | Drug | Patient | Date 113 | +--------+-------------+-----------+------------------------+ 114 | 25 | Indocin | David | 2008-05-01 12:30:52 PM 115 | 50 | Enebrel | Sam | 2008-09-11 8:42:30 AM 116 | 10 | Hydralazine | Christoff | 2019-12-12 9:15:00 AM 117 | 21 | Combivent | Janet | 2018-12-08 3:00:00 PM 118 | 100 | Dilantin | Melanie | 2020-09-14 4:44:44 PM 119 | + + + 120 | ``` 121 | 122 | We can also showcase the type of flexibility the library allows: 123 | 124 | ```csharp 125 | table.SetBorder(Border.Top | Border.Left); 126 | 127 | table.Columns[0].SetHeaderBorder(Border.None); 128 | table.Columns[1].SetHeaderBorder(Border.Left | Border.Top | Border.Right); 129 | table.Columns[2].SetHeaderBorder(Border.None); 130 | table.Columns[3].SetHeaderBorder(Border.Left | Border.Top); 131 | 132 | table.Columns[0].SetDataBorder(Border.Bottom | Border.Right); 133 | table.Columns[1].SetDataBorder(Border.None); 134 | table.Columns[2].SetDataBorder(Border.Left | Border.Bottom); 135 | table.Columns[3].SetDataBorder(Border.Left); 136 | 137 | Console.WriteLine(table.ToPrettyPrintedString()); 138 | ``` 139 | 140 | Output: 141 | 142 | ``` 143 | +-----------------------------------------------------------+ 144 | | Prescriptions 145 | | +-------------+ +------------------------+ 146 | | Dosage | Drug | Patient | Date 147 | | + + + 148 | | 25 | Indocin | David | 2008-05-01 12:30:52 PM 149 | | 50 | Enebrel | Sam | 2008-09-11 8:42:30 AM 150 | | 10 | Hydralazine | Christoff | 2019-12-12 9:15:00 AM 151 | | 21 | Combivent | Janet | 2018-12-08 3:00:00 PM 152 | | 100 | Dilantin | Melanie | 2020-09-14 4:44:44 PM 153 | +--------+ +-----------+ 154 | ``` 155 | 156 | ### Controlling the display of table name and column headers 157 | 158 | We can fully control whether to display the table name, or each individual column header: 159 | 160 | 161 | ```csharp 162 | table.SetShowTableName(false); 163 | 164 | table.Columns[1].SetShowColumnName(false); 165 | table.Columns[3].SetShowColumnName(false); 166 | 167 | Console.WriteLine(table.ToPrettyPrintedString()); 168 | ``` 169 | 170 | Output: 171 | 172 | ``` 173 | +--------+-------------+-----------+------------------------+ 174 | | Dosage | | Patient | | 175 | +--------+-------------+-----------+------------------------+ 176 | | 25 | Indocin | David | 2008-05-01 12:30:52 PM | 177 | | 50 | Enebrel | Sam | 2008-09-11 8:42:30 AM | 178 | | 10 | Hydralazine | Christoff | 2019-12-12 9:15:00 AM | 179 | | 21 | Combivent | Janet | 2018-12-08 3:00:00 PM | 180 | | 100 | Dilantin | Melanie | 2020-09-14 4:44:44 PM | 181 | +--------+-------------+-----------+------------------------+ 182 | ``` 183 | 184 | ### Controlling text alignment of column names and data 185 | 186 | The library has support for controlling text alignment: 187 | 188 | 189 | ```csharp 190 | table.SetTitleTextAlignment(TextAlignment.Left); 191 | 192 | table.Columns[0].SetColumnNameAlignment(TextAlignment.Right); 193 | table.Columns[1].SetColumnNameAlignment(TextAlignment.Left); 194 | 195 | table.Columns[0].SetDataAlignment(TextAlignment.Center); 196 | table.Columns[2].SetDataAlignment(TextAlignment.Right); 197 | 198 | Console.WriteLine(table.ToPrettyPrintedString()); 199 | ``` 200 | 201 | Output: 202 | 203 | ``` 204 | +-----------------------------------------------------------+ 205 | | Prescriptions | 206 | +--------+-------------+-----------+------------------------+ 207 | | Dosage | Drug | Patient | Date | 208 | +--------+-------------+-----------+------------------------+ 209 | | 25 | Indocin | David | 2008-05-01 12:30:52 PM | 210 | | 50 | Enebrel | Sam | 2008-09-11 8:42:30 AM | 211 | | 10 | Hydralazine | Christoff | 2019-12-12 9:15:00 AM | 212 | | 21 | Combivent | Janet | 2018-12-08 3:00:00 PM | 213 | | 100 | Dilantin | Melanie | 2020-09-14 4:44:44 PM | 214 | +--------+-------------+-----------+------------------------+ 215 | ``` 216 | 217 | ### Controlling column widths 218 | 219 | The library automatically sizes column widths based on the maximum width of any individual row. However the user can override this if it happens that the data may be too wide to display in a readable format. In such cases we can explicitly set the column widths: 220 | 221 | 222 | ```csharp 223 | table.Columns[1].SetWidth(8); 224 | table.Columns[3].SetWidth(33); 225 | 226 | Console.WriteLine(table.ToPrettyPrintedString()); 227 | ``` 228 | 229 | Output: 230 | 231 | ``` 232 | +---------------------------------------------------------------+ 233 | | Prescriptions | 234 | +--------+--------+-----------+---------------------------------+ 235 | | Dosage | Drug | Patient | Date | 236 | +--------+--------+-----------+---------------------------------+ 237 | | 25 | Indo.. | David | 2008-05-01 12:30:52 PM | 238 | | 50 | Eneb.. | Sam | 2008-09-11 8:42:30 AM | 239 | | 10 | Hydr.. | Christoff | 2019-12-12 9:15:00 AM | 240 | | 21 | Comb.. | Janet | 2018-12-08 3:00:00 PM | 241 | | 100 | Dila.. | Melanie | 2020-09-14 4:44:44 PM | 242 | +--------+--------+-----------+---------------------------------+ 243 | ``` 244 | 245 | Note that ellipses (`..`) are added if the string cannot be contained within the width requested. 246 | 247 | ### Custom formatting 248 | 249 | By default the library calls the `ToString` API to convert the row objects into strings, however sometimes we require custom printing. The library supports arbitrary control of the string to be printed via a method callback which the user supplies. In this example we want to put an asterisk next to a dosage which exceeds 23 units. We can do this as follows: 250 | 251 | ```csharp 252 | table.Columns[0].SetDataTextFormat((DataColumn c, DataRow r) => 253 | { 254 | Int32 value = r.Field(c); 255 | 256 | return value > 23 ? $"{value} (*)" : $"{value}"; 257 | }); 258 | 259 | Console.WriteLine(table.ToPrettyPrintedString()); 260 | ``` 261 | 262 | Output: 263 | 264 | ``` 265 | +------------------------------------------------------------+ 266 | | Prescriptions | 267 | +---------+-------------+-----------+------------------------+ 268 | | Dosage | Drug | Patient | Date | 269 | +---------+-------------+-----------+------------------------+ 270 | | 25 (*) | Indocin | David | 2008-05-01 12:30:52 PM | 271 | | 50 (*) | Enebrel | Sam | 2008-09-11 8:42:30 AM | 272 | | 10 | Hydralazine | Christoff | 2019-12-12 9:15:00 AM | 273 | | 21 | Combivent | Janet | 2018-12-08 3:00:00 PM | 274 | | 100 (*) | Dilantin | Melanie | 2020-09-14 4:44:44 PM | 275 | +---------+-------------+-----------+------------------------+ 276 | ``` 277 | 278 | ## Tests 279 | 280 | A set of unit tests covers all features of the library by comparing the result against a hand verified output. To run the tests simply: 281 | 282 | ```shell 283 | dotnet build 284 | dotnet test 285 | ``` -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | branches: 3 | include: 4 | - master 5 | tags: 6 | include: 7 | - ?.?.? 8 | 9 | pr: 10 | - master 11 | 12 | pool: 13 | vmImage: 'windows-latest' 14 | 15 | variables: 16 | buildConfiguration: 'Release' 17 | 18 | jobs: 19 | - job: CI 20 | displayName: 'Continuous Integration' 21 | steps: 22 | - task: DotNetCoreCLI@2 23 | displayName: Restore 24 | inputs: 25 | command: 'restore' 26 | feedsToUse: 'select' 27 | 28 | - task: DotNetCoreCLI@2 29 | displayName: Build 30 | inputs: 31 | command: 'build' 32 | projects: '**/*.csproj' 33 | configuration: '$(buildConfiguration)' 34 | 35 | - task: DotNetCoreCLI@2 36 | displayName: Test 37 | inputs: 38 | command: 'test' 39 | projects: '**/*.csproj' 40 | configuration: '$(buildConfiguration)' 41 | 42 | - job: CD 43 | displayName: 'Continuous Deployment' 44 | dependsOn: CI 45 | condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/') 46 | steps: 47 | - task: DotNetCoreCLI@2 48 | displayName: 'Pack' 49 | inputs: 50 | command: 'pack' 51 | packagesToPack: '**/*.csproj;!**/*.Tests.csproj' 52 | configuration: '$(buildConfiguration)' 53 | includesymbols: true 54 | includesource: true 55 | versioningScheme: 'off' 56 | 57 | - task: NuGetCommand@2 58 | inputs: 59 | command: 'push' 60 | packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg' 61 | nuGetFeedType: 'external' 62 | publishFeedCredentials: 'NuGetConnection' --------------------------------------------------------------------------------