Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2c69bc0
Added coding session model
JJHH17 Oct 25, 2025
57eb60d
Added database values
JJHH17 Oct 25, 2025
0809069
Added dapper package
JJHH17 Oct 25, 2025
6c5c0e9
installed sqlite and app.configuration package
JJHH17 Oct 25, 2025
bd25e05
Added database creation, and database model
JJHH17 Oct 25, 2025
c8fbdb1
Added delete methods for database
JJHH17 Oct 25, 2025
f361694
Added third constructor, which calculates duration via the method
JJHH17 Oct 25, 2025
efb1a40
Installed sqlite.core package
JJHH17 Oct 25, 2025
ef55fa8
Added sqlite3 package
JJHH17 Oct 26, 2025
1b5aa54
Added menu method, and method for adding new entries
JJHH17 Oct 26, 2025
92e61bd
Created method for displaying all events
JJHH17 Oct 26, 2025
bc9c1cc
Created method for deleting all entries
JJHH17 Oct 26, 2025
b0a1844
Added method for deleting a single entry
JJHH17 Oct 26, 2025
dd80ef1
Added reference for creating database file and launching UI
JJHH17 Oct 26, 2025
7d0248e
Removed unused using call
JJHH17 Oct 26, 2025
6b4c194
Added testing csproj contents
JJHH17 Oct 26, 2025
23a54f3
Scoped out using statement to be more detailed
JJHH17 Oct 26, 2025
8c613ad
Removed unused stopwatch methods
JJHH17 Oct 26, 2025
d8dae20
Scoped down using methods
JJHH17 Oct 26, 2025
7be6bd1
Added getter for duration
JJHH17 Oct 26, 2025
3fde331
Added duration validation check for correct input
JJHH17 Oct 26, 2025
f1cd9c4
Added reference to main app project
JJHH17 Oct 26, 2025
d89ae0f
Added invalid duration calculation check
JJHH17 Oct 26, 2025
eb4c759
Added zero Duration check test
JJHH17 Oct 26, 2025
1596b93
Added method for checking valid date format
JJHH17 Oct 27, 2025
f82a043
Create README.md for Coding Tracking Application
JJHH17 Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17.Tests/AppTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CodingTrackerApp.JJHH17.Models;
using System;

namespace CodingTrackerApp.JJHH17.Tests;

[TestClass]
public class AppTests
{
[TestMethod]
public void Duration_CalculateDurationCorrectly()
{
var start = "2024-01-01 10:00:00";
var end = "2024-01-01 12:30:45";
var session = new CodingTrackerApp.JJHH17.Models.CodingSession(start, end);

Assert.AreEqual("0 years, 0 months, 0 days, 2 hours, 30 minutes, 45 seconds", session.GetDuration());
}

[TestMethod]
public void Duration_InvalidDurationCalculation_PassesIfTestPasses()
{
var start = "2024-01-01 10:00:00";
var end = "2024-01-01 11:00:00";
var session = new CodingTrackerApp.JJHH17.Models.CodingSession(start, end);

Assert.AreNotEqual("0 years, 0 months, 0 days, 3 hours, 0 minutes, 0 seconds", session.GetDuration());
}

[TestMethod]
public void Duration_ZeroDuration_PassesIfTestPasses()
{
var start = "2024-01-01 10:00:00";
var end = "2024-01-01 10:00:00";
var session = new CodingTrackerApp.JJHH17.Models.CodingSession(start, end);
Assert.AreEqual("0 years, 0 months, 0 days, 0 hours, 0 minutes, 0 seconds", session.GetDuration());
}

[TestMethod]
public void DateInput_ValidDateFormat_PassesIfValidFormat()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 No Value

💡 This tests nothing in your application and brings no value.

{
var dateString = "2024-06-15 14:30";
DateTime parsedDate;
var isValid = DateTime.TryParse(dateString, out parsedDate);
Assert.IsTrue(isValid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="MSTest.TestAdapter" Version="3.6.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.6.2" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CodingTrackerApp.JJHH17\CodingTrackerApp.JJHH17.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Spectre.Console" Version="0.52.0" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.10" />
<PackageReference Include="System.Data.SQLite" Version="2.0.2" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.119" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="databasePath" value="codeTracker.sqlite"/>
<add key="tableName" value="codeTracker"/>
</appSettings>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using Dapper;
using System.Configuration;
using System.Data.SQLite;
using CodingTrackerApp.JJHH17.Models;

namespace CodingTrackerApp.JJHH17.Database;

public class Database
{
private static readonly string dbPath = ConfigurationManager.AppSettings["databasePath"];
private static readonly string tableName = ConfigurationManager.AppSettings["tableName"];
private static readonly string connectionString = $"Data Source={dbPath};";

public static void CreateDatabase()
{
if (!File.Exists(dbPath))
{
SQLiteConnection.CreateFile(dbPath);
Console.WriteLine("Database created successfully");
}
else
{
Console.WriteLine("Database already exists");
}

CreateTable();
}

private static void CreateTable()
{
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();

string tableCreation = @"CREATE TABLE IF NOT EXISTS CodeTracker (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
StartTime TEXT NOT NULL,
EndTime TEXT NOT NULL,
Duration TEXT);";

connection.Execute(tableCreation);
Console.WriteLine("Table created successfully or already exists");
}
}

public static long AddEntry(string startTime, string endTime, string duration)
{
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
var sql = "INSERT INTO CodeTracker (StartTime, EndTime, Duration) VALUES (@StartTime, @EndTime, @Duration);" +
$"SELECT last_insert_rowid();";

var newEntry = new CodingSession(startTime, endTime, duration);

long newId = connection.ExecuteScalar<long>(sql, newEntry);

return newId;
}
}

public static List<CodingSession> GetAllEntries()
{
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
var sql = "SELECT * FROM CodeTracker;";
var entries = connection.Query<CodingSession>(sql).ToList();
return entries;
}
}

public static void DeleteAllEntries()
{
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
var sql = $"DELETE FROM {tableName};";
connection.Execute(sql);
}
}

public static void DeleteEntryById(long id)
{
using (var connection = new SQLiteConnection(connectionString))
{
// Get list of existing entries for ID selection
GetAllEntries();

connection.Open();
var sql = $"DELETE FROM {tableName} WHERE Id = @Id;";
connection.Execute(sql, new { Id = id } );
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
namespace CodingTrackerApp.JJHH17.Models;

public class CodingSession
{
public long Id { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
public string Duration { get; set; }

public DateTime? stopwatchStartTime;
public DateTime? stopwatchEndTime;

public CodingSession()
{
}

public CodingSession(string startTime, string endTime)
{
StartTime = startTime;
EndTime = endTime;
CalculateDuration();
}

public CodingSession(string startTime, string endTime, string duration)
{
StartTime = startTime;
EndTime = endTime;
Duration = duration;
}

public void CalculateDuration()
{
DateTime start = DateTime.Parse(StartTime);
DateTime end = DateTime.Parse(EndTime);

int years = end.Year - start.Year;
int months = end.Month - start.Month;
int days = end.Day - start.Day;

if (days < 0)
{
months--;
var previousMonth = end.AddMonths(-1);
days += DateTime.DaysInMonth(previousMonth.Year, previousMonth.Month);
}

if (months < 0)
{
years--;
months += 12;
}

TimeSpan timespan = end - start;

int totalDays = (int)timespan.TotalDays;
int totalHours = (int)timespan.TotalHours % 24;
int totalMinutes = (int)timespan.TotalMinutes % 60;
int totalSeconds = (int)timespan.TotalSeconds % 60;

Duration = $"{years} years, {months} months, {days} days, {totalHours} hours, {totalMinutes} minutes, {totalSeconds} seconds";
}

public string GetDuration()
{
return Duration;
}
}
12 changes: 12 additions & 0 deletions CodingTrackerApp.JJHH17/CodingTrackerApp.JJHH17/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Menu = CodingTrackerApp.JJHH17.UserInterface;

namespace CodingTrackerApp.JJHH17;

class Program
{
public static void Main(string[] args)
{
Database.Database.CreateDatabase();
Menu.Running();
}
}
Loading