├── .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 | [](https://github.com/fjeremic/DataTablePrettyPrinter/blob/master/LICENSE)
3 | [](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'
--------------------------------------------------------------------------------