diff --git a/App/Program.cs b/App/Program.cs
index c4c26a8..5ce527e 100644
--- a/App/Program.cs
+++ b/App/Program.cs
@@ -1,22 +1,68 @@
-using System;
-
-namespace App
-{
- public class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("Run with `dotnet test` from CSharpInterview/AppTest");
- }
-
- public static string ConvertToTitleCase(string inpStr)
- {
- return inpStr;
- }
-
- public static string ConvertUnixToDateString(long? inpUnixSeconds)
- {
- return inpUnixSeconds.ToString();
- }
- }
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace App
+{
+ public class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Run with `dotnet test` from CSharpInterview/AppTest");
+ }
+
+ ///
+ /// Challenge 1
+ /// Create a function that takes in a constant-formatted (all caps, words separated by underscores) string and returns the string in "title case" (see examples below). The function should
+ /// remove all non alphanumeric characters and replace them with spaces. But no spaces at the end of the result. A null input should throw an error.
+ ///
+ /// If you so choose feel free to leverage third party libraries to complete your solution.
+ ///
+ /// For example: "THIS_INPUT" should return "This Input" "CASE-THREE_extra[chars]///" should return "Case Three Extra Chars"
+ ///
+ public static string ConvertToTitleCase(string input)
+ {
+
+ if (string.IsNullOrEmpty(input)) // Check for invalid input.
+ {
+ throw new ArgumentNullException("The input to this function cannot be null.");
+ }
+
+ Regex Expression = new Regex("[^a-zA-Z0-9]");
+ string[] Words = Expression.Replace(input, " ").Split(new char[] { ' ' }); // Use the regular expression to replace non-alphanumeric characters with space, and split into an array.
+ StringBuilder Result = new StringBuilder();
+ foreach (string Word in Words) // Iterate through the words of the array.
+ {
+ if (!string.IsNullOrEmpty(Word)) // Only take action on words that are not empty.
+ {
+ Result.Append(Word[0].ToString().ToUpper() + Word.Substring(1).ToLower() + " "); // Append the capitalized first letter of the word, and the lowercase rest of the word.
+ }
+ }
+ return Result.ToString().Trim(); // Output the formatted list of words, trimmed to remove the trailing space.
+ }
+
+ ///
+ /// Challenge 2
+ /// Create a function that takes in a unix epoch time in seconds(long data type) and returns a String that is the input timestamp converted and formatted as month day, year (see below).
+ /// If no timestamp is given the function should return today’s date. If the input is null or has an incorrect type, an error should be thrown.
+ ///
+ /// If you so choose feel free to leverage third party libraries to complete your solution.
+ ///
+ /// For example, passing a unix epoch time 1499144400 in seconds (long data type) would return "July 4, 2017" in this date format(string data type).
+ ///
+ ///
+ /// I decided to omit checks for no timestamp given, since the unix epoch time is the number of seconds since 1-1-1970 (00:00 GMT), there is no such thing as a missing timestamp. All values
+ /// for the long data type, including negative and zero values, are valid unix timestamps, and this function will convert them accordingly.
+ ///
+ public static string ConvertUnixToDateString(long? unixTime)
+ {
+ if (unixTime == null) // Check for invalid input.
+ {
+ throw new ArgumentNullException("The input to this function cannot be null.");
+ }
+
+ // Using DateTimeOffset, generate a DateTime object from the unixTime paramter. This is then converted to a string using a format code to get the desired format, and returned.
+ return DateTimeOffset.FromUnixTimeSeconds((long)unixTime).DateTime.ToString("MMMM d, yyyy");
+ }
+ }
}
\ No newline at end of file
diff --git a/AppTest/Program.Tests.cs b/AppTest/Program.Tests.cs
index f948724..1be227c 100644
--- a/AppTest/Program.Tests.cs
+++ b/AppTest/Program.Tests.cs
@@ -1,78 +1,193 @@
-using System;
-using App;
-using Xunit;
-
-namespace AppTest
-{
- public class ProgramTests
- {
- [Fact]
- public void ConvertToTitleCase_Simple()
- {
- // Given
- var testStr = "TITLE_CASE";
-
- // When
- var actual = Program.ConvertToTitleCase(testStr);
-
- // Then
- var expected = "Title Case";
- Assert.Equal(expected, actual);
- }
-
- [Fact]
- public void ConvertToTitleCase_Numbers()
- {
- // Given
- var testStr = "NUMBER_3";
-
- // When
- var actual = Program.ConvertToTitleCase(testStr);
-
- // Then
- var expected = "Number 3";
- Assert.Equal(expected, actual);
- }
-
- [Fact]
- public void ConvertToTitleCase_OtherChars()
- {
- // Given
- var testStr = " TRUTH-TRACK ";
-
- // When
- var actual = Program.ConvertToTitleCase(testStr);
-
- // Then
- var expected = "Truth Track";
- Assert.Equal(expected, actual);
- }
-
- [Fact]
- public void ConvertUnixToDateString_Simple()
- {
- // Given
- var testStamp = 1604352245L;
-
- // When
- var actual = Program.ConvertUnixToDateString(testStamp);
-
- // Then
- var expected = "November 2, 2020";
- Assert.Equal(expected, actual);
- }
-
- [Fact]
- public void ConvertUnixToDateString_Null()
- {
- // Given
- long? testStamp = null;
-
- // When
- Action action = () => Program.ConvertUnixToDateString(testStamp);
-
- // Then
- Assert.Throws(action);
- }
- }
+using System;
+using App;
+using Xunit;
+
+namespace AppTest
+{
+ public class ProgramTests
+ {
+ [Fact]
+ public void ConvertToTitleCase_Simple()
+ {
+ // Given
+ var testStr = "TITLE_CASE";
+
+ // When
+ var actual = Program.ConvertToTitleCase(testStr);
+
+ // Then
+ var expected = "Title Case";
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void ConvertToTitleCase_Numbers()
+ {
+ // Given
+ var testStr = "NUMBER_3";
+
+ // When
+ var actual = Program.ConvertToTitleCase(testStr);
+
+ // Then
+ var expected = "Number 3";
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void ConvertToTitleCase_OtherChars()
+ {
+ // Given
+ var testStr = " TRUTH-TRACK ";
+
+ // When
+ var actual = Program.ConvertToTitleCase(testStr);
+
+ // Then
+ var expected = "Truth Track";
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void ConvertToTitleCase_OtherChars2()
+ {
+ // Given
+ var testStr = "CASE-THREE_extra[chars]///";
+
+ // When
+ var actual = Program.ConvertToTitleCase(testStr);
+
+ // Then
+ var expected = "Case Three Extra Chars";
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void ConvertToTitleCase_Null()
+ {
+ // Given
+ string testStr = null;
+
+ // When
+ Action action = () => Program.ConvertToTitleCase(testStr);
+
+ // Then
+ Assert.Throws(action);
+ }
+
+ // NOTE: I decided that an empty string should also throw an exception.
+ [Fact]
+ public void ConvertToTitleCase_Empty()
+ {
+ // Given
+ string testStr = string.Empty;
+
+ // When
+ Action action = () => Program.ConvertToTitleCase(testStr);
+
+ // Then
+ Assert.Throws(action);
+ }
+
+ [Fact]
+ public void ConvertUnixToDateString_Simple()
+ {
+ // Given
+ var testStamp = 1604352245L;
+
+ // When
+ var actual = Program.ConvertUnixToDateString(testStamp);
+
+ // Then
+ var expected = "November 2, 2020";
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void ConvertUnixToDateString_Null()
+ {
+ // Given
+ long? testStamp = null;
+
+ // When
+ Action action = () => Program.ConvertUnixToDateString(testStamp);
+
+ // Then
+ // NOTE: Modified this test to detect ArgumentNullException.
+ Assert.Throws(action);
+ }
+
+ [Fact]
+ public void ConvertUnixToDateString_Original()
+ {
+ // Given
+ var testStamp = 1499144400;
+
+ // When
+ var actual = Program.ConvertUnixToDateString(testStamp);
+
+ // Then
+ var expected = "July 4, 2017";
+ Assert.Equal(expected, actual);
+ }
+
+ // Note: The following tests had their expected results generated using epochconverter.com. The assumption is that the time zone is GMT.
+ [Fact]
+ public void ConvertUnixToDateString_Zero()
+ {
+ // Given
+ var testStamp = 0;
+
+ // When
+ var actual = Program.ConvertUnixToDateString(testStamp);
+
+ // Then
+ var expected = "January 1, 1970";
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void ConvertUnixToDateString_Negative()
+ {
+ // Given
+ var testStamp = -561600;
+
+ // When
+ var actual = Program.ConvertUnixToDateString(testStamp);
+
+ // Then
+ var expected = "December 25, 1969";
+ Assert.Equal(expected, actual);
+ }
+
+ // These datestamps are generated to be one second before and after midnight on May 21, 1982. This is to demonstrate that even a single digit difference in timestamp can result in a
+ // different date string.
+ [Fact]
+ public void ConvertUnixToDateString_OffByOne_1()
+ {
+ // Given
+ var testStamp = 390787200;
+
+ // When
+ var actual = Program.ConvertUnixToDateString(testStamp);
+
+ // Then
+ var expected = "May 21, 1982";
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void ConvertUnixToDateString_OffByOne_2()
+ {
+ // Given
+ var testStamp = 390787199;
+
+ // When
+ var actual = Program.ConvertUnixToDateString(testStamp);
+
+ // Then
+ var expected = "May 20, 1982";
+ Assert.Equal(expected, actual);
+ }
+ }
}
\ No newline at end of file