diff --git a/ConTabs.Tests/ConTabs.Tests.csproj b/ConTabs.Tests/ConTabs.Tests.csproj
index 1f31e73..f75ed44 100644
--- a/ConTabs.Tests/ConTabs.Tests.csproj
+++ b/ConTabs.Tests/ConTabs.Tests.csproj
@@ -53,6 +53,7 @@
+
diff --git a/ConTabs.Tests/UsageTests.cs b/ConTabs.Tests/UsageTests.cs
new file mode 100644
index 0000000..85feb3f
--- /dev/null
+++ b/ConTabs.Tests/UsageTests.cs
@@ -0,0 +1,42 @@
+using ConTabs.TestData;
+using NUnit.Framework;
+using Shouldly;
+using System;
+
+namespace ConTabs.Tests
+{
+ [TestFixture]
+ class UsageTests
+ {
+ [Test]
+ public void OnceFormatSet_FormatCanBeUpdated()
+ {
+ // Arrange
+ var tableObj = Table.Create();
+ tableObj.TableStyle = Style.Default;
+
+ // Act
+ tableObj.TableStyle = Style.Heavy;
+ var result = tableObj.ToString();
+
+ // Assert
+ result[0].ShouldBe('#');
+ }
+
+ [Test]
+ public void OnceFormatSet_CornerCanBeUpdated()
+ {
+ // Arrange
+ var tableObj = Table.Create();
+ tableObj.TableStyle = Style.Default;
+
+ // Act
+ tableObj.TableStyle.Corners.CornerTopLeft = '$';
+ var result = tableObj.ToString();
+
+ // Assert
+ result[0].ShouldBe('$');
+ }
+
+ }
+}
diff --git a/ConTabs/Corners.cs b/ConTabs/Corners.cs
new file mode 100644
index 0000000..aa385f4
--- /dev/null
+++ b/ConTabs/Corners.cs
@@ -0,0 +1,50 @@
+namespace ConTabs
+{
+ public class Corners
+ {
+ private readonly char[,] cornerChars = new char[3, 3];
+
+ /*
+ * ╔═══╤═════╤═════╤═════╗
+ * ║ │ 0 │ 1 │ 2 ║
+ * ╠═══╪═════╪═════╪═════╣
+ * ║ 0 │ TL │ TNU │ TR ║
+ * ╟───┼─────┼─────┼─────╢
+ * ║ 1 │ TNL │ I │ TNR ║
+ * ╟───┼─────┼─────┼─────╢
+ * ║ 2 │ BL │ TND │ BR ║
+ * ╚═══╧═════╧═════╧═════╝
+ *
+ */
+
+ public char CornerTopLeft { get { return cornerChars[0, 0]; } set { cornerChars[0, 0] = value; } }
+ public char CornerTopRight { get { return cornerChars[2, 0]; } set { cornerChars[2, 0] = value; } }
+ public char CornerBottomLeft { get { return cornerChars[0, 2]; } set { cornerChars[0, 2] = value; } }
+ public char CornerBottomRight { get { return cornerChars[2, 2]; } set { cornerChars[2, 2] = value; } }
+
+ public char Intersection { get { return cornerChars[1, 1]; } set { cornerChars[1, 1] = value; } }
+ public char TeeNoUp { get { return cornerChars[1, 0]; } set { cornerChars[1, 0] = value; } }
+ public char TeeNoRight { get { return cornerChars[2, 1]; } set { cornerChars[2, 1] = value; } }
+ public char TeeNoDown { get { return cornerChars[1, 2]; } set { cornerChars[1, 2] = value; } }
+ public char TeeNoLeft { get { return cornerChars[0, 1]; } set { cornerChars[0, 1] = value; } }
+
+ public char this[int i, int j]
+ {
+ get
+ {
+ return cornerChars[i, j];
+ }
+ }
+
+ public void SetAllCorners(char corner)
+ {
+ for(int i=0;i where T:class
+ public partial class Table
{
- private StringBuilder sb;
- private Table table;
- private Style style;
-
- public static string BuildOutput(Table t, Style s)
+ private sealed class OutputBuilder where T2 : class
{
- var instance = new OutputBuilder(t, s);
- return instance.sb.ToString();
- }
+ private readonly StringBuilder sb;
+ private readonly Table table;
+ private readonly Style style;
- private OutputBuilder(Table t, Style s)
- {
- table = t;
- style = s;
- sb = new StringBuilder();
- HLine(TopMidBot.Top); NewLine();
- Headers(); NewLine();
- HLine(TopMidBot.Mid); NewLine();
- if (table.Data == null || table.Data.Count() == 0)
+ internal static string BuildOutput(Table t, Style s)
{
- NoDataLine(); NewLine();
+ var instance = new OutputBuilder(t, s);
+ return instance.sb.ToString();
}
- else
+
+ private OutputBuilder(Table t, Style s)
{
- for (int i = 0; i < table.Data.Count(); i++)
+ table = t;
+ style = s;
+ sb = new StringBuilder();
+ HLine(TopMidBot.Top); NewLine();
+ Headers(); NewLine();
+ HLine(TopMidBot.Mid); NewLine();
+ if (table.Data == null || table.Data.Count() == 0)
+ {
+ NoDataLine(); NewLine();
+ }
+ else
{
- DataLine(i); NewLine();
+ for (int i = 0; i < table.Data.Count(); i++)
+ {
+ DataLine(i); NewLine();
+ }
}
+ HLine(TopMidBot.Bot);
}
- HLine(TopMidBot.Bot);
- }
- private void NewLine()
- {
- sb.Append(Environment.NewLine);
- }
+ private void NewLine()
+ {
+ sb.Append(Environment.NewLine);
+ }
- private void HLine(TopMidBot v)
- {
- sb.Append(GetCorner(v, LeftCentreRight.Left));
- for (int i = 0; i < table._colsShown.Count; i++)
+ private void HLine(TopMidBot v)
{
- sb.Append(new string(style.Floor, table._colsShown[i].MaxWidth + 2));
- if (i < table._colsShown.Count - 1) sb.Append(GetCorner(v, LeftCentreRight.Centre));
+ sb.Append(GetCorner(v, LeftCentreRight.Left));
+ for (int i = 0; i < table._colsShown.Count; i++)
+ {
+ sb.Append(new string(style.Floor, table._colsShown[i].MaxWidth + 2));
+ if (i < table._colsShown.Count - 1) sb.Append(GetCorner(v, LeftCentreRight.Centre));
+ }
+ sb.Append(GetCorner(v, LeftCentreRight.Right));
}
- sb.Append(GetCorner(v, LeftCentreRight.Right));
- }
- private void NoDataLine()
- {
- var noDataText = "no data";
- int colWidths = table._colsShown.Sum(c => c.MaxWidth);
- int innerWidth = colWidths + (3 * table._colsShown.Count) - 1;
- int leftPad = (innerWidth - noDataText.Length) / 2;
- int rightPad = innerWidth - (leftPad + noDataText.Length);
- sb.Append(style.Wall + new String(' ', leftPad) + noDataText + new string(' ', rightPad) + style.Wall);
- }
+ private void NoDataLine()
+ {
+ var noDataText = "no data";
+ int colWidths = table._colsShown.Sum(c => c.MaxWidth);
+ int innerWidth = colWidths + (3 * table._colsShown.Count) - 1;
+ int leftPad = (innerWidth - noDataText.Length) / 2;
+ int rightPad = innerWidth - (leftPad + noDataText.Length);
+ sb.Append(style.Wall + new String(' ', leftPad) + noDataText + new string(' ', rightPad) + style.Wall);
+ }
- private void Headers()
- {
- sb.Append(style.Wall);
- foreach (var col in table._colsShown)
+ private void Headers()
{
- sb.Append(" " + col.ColumnName + new string(' ', col.MaxWidth - col.ColumnName.Length) + " " + style.Wall);
+ sb.Append(style.Wall);
+ foreach (var col in table._colsShown)
+ {
+ sb.Append(" " + col.ColumnName + new string(' ', col.MaxWidth - col.ColumnName.Length) + " " + style.Wall);
+ }
}
- }
- private void DataLine(int i)
- {
- sb.Append(style.Wall);
- foreach (var col in table._colsShown)
+ private void DataLine(int i)
{
- var value = col.StringValForCol(col.Values[i]);
- sb.Append(" " + value + new string(' ', col.MaxWidth - value.Length) + " " + style.Wall);
+ sb.Append(style.Wall);
+ foreach (var col in table._colsShown)
+ {
+ var value = col.StringValForCol(col.Values[i]);
+ sb.Append(" " + value + new string(' ', col.MaxWidth - value.Length) + " " + style.Wall);
+ }
}
- }
- private enum TopMidBot
- {
- Top,
- Mid,
- Bot
- }
+ private enum TopMidBot
+ {
+ Top,
+ Mid,
+ Bot
+ }
- private enum LeftCentreRight
- {
- Left,
- Centre,
- Right
- }
+ private enum LeftCentreRight
+ {
+ Left,
+ Centre,
+ Right
+ }
- private char GetCorner(TopMidBot v, LeftCentreRight h)
- {
- return style.Corners[(int)h, (int)v];
+ private char GetCorner(TopMidBot v, LeftCentreRight h)
+ {
+ return style.Corners[(int)h, (int)v];
+ }
}
}
}
diff --git a/ConTabs/Styles.cs b/ConTabs/Styles.cs
index 8caea4a..32ae2eb 100644
--- a/ConTabs/Styles.cs
+++ b/ConTabs/Styles.cs
@@ -1,4 +1,6 @@
-namespace ConTabs
+using System;
+
+namespace ConTabs
{
public class Style
{
@@ -6,72 +8,78 @@ public class Style
public char Wall { get; set; }
public char Floor { get; set; }
- public char[,] Corners = new char[3, 3];
-
- /*
- * ╔═══╤═════╤═════╤═════╗
- * ║ │ 0 │ 1 │ 2 ║
- * ╠═══╪═════╪═════╪═════╣
- * ║ 0 │ TL │ TNU │ TR ║
- * ╟───┼─────┼─────┼─────╢
- * ║ 1 │ TNR │ I │ TNL ║
- * ╟───┼─────┼─────┼─────╢
- * ║ 2 │ BL │ TND │ BR ║
- * ╚═══╧═════╧═════╧═════╝
- *
- */
-
- public char CornerTopLeft { get { return Corners[0, 0]; } set { Corners[0, 0] = value; } }
- public char CornerTopRight { get { return Corners[2, 0]; } set { Corners[2, 0] = value; } }
- public char CornerBottomLeft { get { return Corners[0, 2]; } set { Corners[0, 2] = value; } }
- public char CornerBottomRight { get { return Corners[2, 2]; } set { Corners[2, 2] = value; } }
-
- public char Intersection { get { return Corners[1, 1]; } set { Corners[1, 1] = value; } }
- public char TeeNoUp { get { return Corners[1, 0]; } set { Corners[1, 0] = value; } }
- public char TeeNoRight { get { return Corners[0, 1]; } set { Corners[0, 1] = value; } }
- public char TeeNoDown { get { return Corners[1, 2]; } set { Corners[1, 2] = value; } }
- public char TeeNoLeft { get { return Corners[2, 1]; } set { Corners[2, 1] = value; } }
+ public Corners Corners { get; set; }
public Style(char wall, char floor, char corners)
{
Wall = wall;
Floor = floor;
-
- CornerTopLeft = corners;
- CornerTopRight = corners;
- CornerBottomLeft = corners;
- CornerBottomRight = corners;
- Intersection = corners;
- TeeNoUp = corners;
- TeeNoRight = corners;
- TeeNoDown = corners;
- TeeNoLeft = corners;
+ Corners = new Corners();
+ Corners.SetAllCorners(corners);
}
- public Style(char wall, char floor, char tl, char tr, char bl, char br, char i, char tnu, char tnr, char tnd, char tnl)
+ public Style(char wall, char floor, Corners corners)
{
Wall = wall;
Floor = floor;
-
- CornerTopLeft = tl;
- CornerTopRight = tr;
- CornerBottomLeft = bl;
- CornerBottomRight = br;
-
- Intersection = i;
- TeeNoUp = tnu;
- TeeNoRight = tnr;
- TeeNoDown = tnd;
- TeeNoLeft = tnl;
+ Corners = corners;
}
+ // Built-in styles
public static Style Default => new Style('|', '-', '+');
public static Style Heavy => new Style('#', '=', '#');
- public static Style UnicodePipes => new Style('║', '═', '╔', '╗', '╚', '╝', '╬', '╦', '╠', '╩', '╣');
+ public static Style UnicodePipes => new Style('║', '═', new Corners {
+ CornerTopLeft = '╔',
+ CornerTopRight = '╗',
+ CornerBottomLeft = '╚',
+ CornerBottomRight = '╝',
+ Intersection = '╬',
+ TeeNoUp = '╦',
+ TeeNoLeft = '╠',
+ TeeNoDown = '╩',
+ TeeNoRight = '╣'
+ });
+ // Deprecated setters/getters
+ [Obsolete("Use Corners.CornerTopLeft")]
+ public char CornerTopLeft { get { return Corners[0, 0]; } set { Corners.CornerTopLeft = value; } }
+ [Obsolete("Use Corners.CornerTopRight")]
+ public char CornerTopRight { get { return Corners[2, 0]; } set { Corners.CornerTopRight = value; } }
+ [Obsolete("Use Corners.CornerBottomLeft")]
+ public char CornerBottomLeft { get { return Corners[0, 2]; } set { Corners.CornerBottomLeft = value; } }
+ [Obsolete("Use Corners.CornerBottomRight")]
+ public char CornerBottomRight { get { return Corners[2, 2]; } set { Corners.CornerBottomRight = value; } }
+ [Obsolete("Use Corners.Intersection")]
+ public char Intersection { get { return Corners[1, 1]; } set { Corners.Intersection = value; } }
+ [Obsolete("Use Corners.TeeNoUp")]
+ public char TeeNoUp { get { return Corners[1, 0]; } set { Corners.TeeNoUp = value; } }
+ [Obsolete("Use Corners.TeeNoRight")]
+ public char TeeNoRight { get { return Corners[2, 1]; } set { Corners.TeeNoRight = value; } }
+ [Obsolete("Use Corners.TeeNoDown")]
+ public char TeeNoDown { get { return Corners[1, 2]; } set { Corners.TeeNoDown = value; } }
+ [Obsolete("Use Corners.TeeNoLeft")]
+ public char TeeNoLeft { get { return Corners[0, 1]; } set { Corners.TeeNoLeft = value; } }
+
+ // Old constructor with too many params
+ [Obsolete]
+ public Style(char wall, char floor, char tl, char tr, char bl, char br, char i, char tnu, char tnr, char tnd, char tnl)
+ {
+ Wall = wall;
+ Floor = floor;
+
+ Corners.CornerTopLeft = tl;
+ Corners.CornerTopRight = tr;
+ Corners.CornerBottomLeft = bl;
+ Corners.CornerBottomRight = br;
+ Corners.Intersection = i;
+ Corners.TeeNoUp = tnu;
+ Corners.TeeNoRight = tnr;
+ Corners.TeeNoDown = tnd;
+ Corners.TeeNoLeft = tnl;
+ }
}
}
diff --git a/ConTabs/Table.cs b/ConTabs/Table.cs
index ff664bf..c213fa0 100644
--- a/ConTabs/Table.cs
+++ b/ConTabs/Table.cs
@@ -5,7 +5,7 @@
namespace ConTabs
{
- public class Table where T:class
+ public partial class Table where T:class
{
public List Columns { get; set; }
internal List _colsShown => Columns.Where(c => !c.Hide).ToList();
diff --git a/appveyor.yml b/appveyor.yml
index 43bff63..6ad1bc6 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -14,7 +14,7 @@ build:
after_test:
# Tell OpenCover to generate coverage.xml
- - cmd: packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -filter:"+[ConTabs]*" -target:"packages\NUnit.ConsoleRunner.3.7.0\tools\nunit3-console.exe" -targetargs:"/domain:single ConTabs.Tests/bin/debug/ConTabs.Tests.dll" -output:coverage.xml
+ - cmd: packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -register:user -filter:"+[ConTabs]*" -target:"packages\NUnit.ConsoleRunner.3.7.0\tools\nunit3-console.exe" -targetargs:"/domain:single ConTabs.Tests/bin/debug/ConTabs.Tests.dll" -output:coverage.xml -excludebyattribute:"System.ObsoleteAttribute"
# Send coverage.xml to Coveralls
- cmd: packages\coveralls.io.1.4.2\tools\coveralls.net.exe --opencover coverage.xml -r %COVERALLS_REPO_TOKEN%
\ No newline at end of file