Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 4 additions & 8 deletions StudentManager.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Global
StartupItem = StudentManager\StudentManager.csproj
Policies = $0
$0.TextStylePolicy = $1
$1.RemoveTrailingWhitespace = True
$1.inheritsSet = VisualStudio
$1.inheritsScope = text/plain
$1.scope = text/x-csharp
Expand All @@ -31,12 +32,6 @@ Global
$2.EventAddBraceStyle = NextLine
$2.EventRemoveBraceStyle = NextLine
$2.StatementBraceStyle = NextLine
$2.ElseNewLinePlacement = NewLine
$2.CatchNewLinePlacement = NewLine
$2.FinallyNewLinePlacement = NewLine
$2.WhileNewLinePlacement = DoNotCare
$2.ArrayInitializerWrapping = DoNotChange
$2.ArrayInitializerBraceStyle = NextLine
$2.BeforeMethodDeclarationParentheses = False
$2.BeforeMethodCallParentheses = False
$2.BeforeConstructorDeclarationParentheses = False
Expand All @@ -48,8 +43,9 @@ Global
$2.scope = text/x-csharp
$0.TextStylePolicy = $3
$3.FileWidth = 120
$3.TabsToSpaces = False
$3.inheritsSet = VisualStudio
$3.TabWidth = 4
$3.EolMarker = Unix
$3.inheritsSet = Mono
$3.inheritsScope = text/plain
$3.scope = text/plain
$0.StandardHeader = $4
Expand Down
39 changes: 22 additions & 17 deletions StudentManager.userprefs
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
<Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug|x86" />
<MonoDevelop.Ide.Workbench ActiveDocument="StudentManager/Tests/TestPersistence.cs">
<MonoDevelop.Ide.Workbench ActiveDocument="StudentManager/Main.cs">
<Files>
<File FileName="StudentManager/Main.cs" Line="10" Column="10" />
<File FileName="StudentManager/Identity.cs" Line="31" Column="26" />
<File FileName="StudentManager/Tests/TestManager.cs" Line="116" Column="1" />
<File FileName="StudentManager/Tests/TestPersistence.cs" Line="95" Column="1" />
<File FileName="StudentManager/TextInterface.cs" Line="217" Column="35" />
<File FileName="StudentManager/XMLDatabase.cs" Line="48" Column="57" />
<File FileName="StudentManager/Main.cs" Line="4" Column="22" />
<File FileName="StudentManager/Class.cs" Line="18" Column="23" />
<File FileName="StudentManager/Manager.cs" Line="60" Column="11" />
<File FileName="StudentManager/Student.cs" Line="1" Column="1" />
<File FileName="StudentManager/Tests/TestManager.cs" Line="79" Column="10" />
<File FileName="StudentManager/Tests/TestPersistence.cs" Line="58" Column="32" />
<File FileName="StudentManager/Identity.cs" Line="28" Column="36" />
<File FileName="StudentManager/TextInterface.cs" Line="217" Column="35" />
<File FileName="StudentManager/XMLDatabase.cs" Line="48" Column="57" />
<File FileName="StudentManager/Main.cs" Line="16" Column="33" />
<File FileName="StudentManager/Class.cs" Line="18" Column="23" />
<File FileName="StudentManager/Manager.cs" Line="55" Column="21" />
<File FileName="StudentManager/Student.cs" Line="1" Column="1" />
<File FileName="StudentManager/Tests/TestManager.cs" Line="79" Column="10" />
<File FileName="StudentManager/Tests/TestPersistence.cs" Line="58" Column="32" />
<File FileName="StudentManager/Identity.cs" Line="50" Column="1" />
</Files>
<Pads>
<Pad Id="ProjectPad">
<State expanded="True">
<Node name="StudentManager" expanded="True">
<Node name="Tests" expanded="True">
<Node name="TestPersistence.cs" selected="True" />
</Node>
<Node name="Tests" expanded="True" />
<Node name="Main.cs" selected="True" />
</Node>
</State>
</Pad>
Expand All @@ -24,15 +37,7 @@
<State />
</Pad>
<Pad Id="MonoDevelop.NUnit.TestPad">
<State expanded="True">
<Node name="StudentManager" expanded="True">
<Node name="StudentManager" expanded="True">
<Node name="TestPersistence" expanded="True">
<Node name="SaveSortedSet" selected="True" />
</Node>
</Node>
</Node>
</State>
<State expanded="True" selected="True" />
</Pad>
</Pads>
</MonoDevelop.Ide.Workbench>
Expand Down
6 changes: 4 additions & 2 deletions StudentManager/Class.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

namespace StudentManager
{
public struct Room
public class Room : Identity
{
[Identity.ID]
public String Name { get; set; }
}

Expand All @@ -15,8 +16,9 @@ public struct TimeSlot
public DateTime EndTime { get; set; }
}

public class Class: Identity
public class Class : Identity
{
[Identity.ID]
public string Name { get; set; }

public string Teacher { get; set; }
Expand Down
77 changes: 61 additions & 16 deletions StudentManager/Identity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,75 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
using System;
using System.Linq;
using System.Reflection;

namespace StudentManager
{
public abstract class Identity: IComparable<Identity>
/// <summary>
/// Base class for identities.
/// </summary>
/// <remarks>
/// The single purpose for this class' existence is to provide
/// simple and uniform ID and equality check. Inheriting classes
/// are expected to have a single public property decorated with
/// the [ID] attribute, which will be used in equality comparisions.
/// If there are multiple properties with ID attribute, only the
/// first one will be used.
/// </remarks>
public abstract class Identity : IEquatable<Identity>
{
public int ID { get; set; }


public int CompareTo(Identity other)
[AttributeUsage(System.AttributeTargets.Property)]
public class IDAttribute : System.Attribute
{
return this.ID - other.ID;
}

public override bool Equals(Object other)

MethodInfo IdGetMethod;

public Identity()
{
var idProperty = (from prop in this.GetType().GetProperties()
from attr in prop.GetCustomAttributes(false)
where attr is IDAttribute
select prop).SingleOrDefault();

// Not null, readable and not an indexer
if (idProperty != null &&
idProperty.CanRead &&
idProperty.GetIndexParameters().Length == 0)
{
IdGetMethod = idProperty.GetGetMethod();
}
}

#region IEquatable[Identity] implementation
public bool Equals(Identity other)
{
if (this.IdGetMethod != null)
{
object otherId = other.IdGetMethod.Invoke(other, null);
object thisId = this.IdGetMethod.Invoke(this, null);
return thisId.Equals(otherId);
} else
{
return base.Equals(other);
}
}

public override bool Equals(object obj)
{
var other = obj as Identity;
return other != null && this.Equals(other);
}

public override int GetHashCode()
{
if (other == null)
return false;

Identity _other = other as Identity;
if (_other == null)
return false;

return this.ID == _other.ID;
if (this.IdGetMethod != null)
return this.IdGetMethod.Invoke(this, null).GetHashCode();
else
return base.GetHashCode();
}
#endregion
}
}

3 changes: 3 additions & 0 deletions StudentManager/Main.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using StudentManager.TextUi;

namespace StudentManager
{
class MainClass
{
public static void Main(string[] args)
{
Manager m = new Manager();
new MainScreen(m).Start();
}
}
}
41 changes: 34 additions & 7 deletions StudentManager/Manager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ class Manager
{
// Mutable collections, expected to be edited by
// users.
public SortedSet<Class> Classes { get; private set; }
public HashSet<Class> Classes { get; private set; }

public SortedSet<Student> Students { get; private set; }
public HashSet<Student> Students { get; private set; }

public HashSet<Room> Rooms { get; private set; }

Expand All @@ -29,27 +29,54 @@ public IEnumerable<Tuple<Class, Student>> ClassStudents
public IEnumerable<Tuple<Class, Room, TimeSlot>> Allocation
{ get { return this.allocation; } }

/// <summary>
/// In memory constructor. All data is created fresh. Mostly for testing
/// purposes.
/// </summary>
public Manager()
{
Classes = new SortedSet<Class>();
Students = new SortedSet<Student>();
Classes = new HashSet<Class>();
Students = new HashSet<Student>();
Rooms = new HashSet<Room>();
TimeSlots = new HashSet<TimeSlot>();
classStudents = new HashSet<Tuple<Class, Student>>();
allocation = new HashSet<Tuple<Class, Room, TimeSlot>>();
}

public Student GetStudentById(int id)
/// <summary>
/// Initializes with external data sources.
/// </summary>
/// <param name='database'>
/// A database accessing object.
/// </param>
/// <param name='UriMapping'>
/// A mapping between resources' name and their URI. The list of resources that
/// we need is: classes, students, rooms, timeslots, classstudents, allocation.
/// </param>
public Manager(IPersistenceService database, Dictionary<String, String> UriMapping)
{
Classes = new HashSet<Class>(database.load<List<Class>>(UriMapping["classes"]));
Students = new HashSet<Student>(database.load<List<Student>>(UriMapping["students"]));
}

public Student GetStudentById(String id)
{
return (from student in this.Students
where student.ID == id
select student).SingleOrDefault();
}

public Class GetClassById(int id)
// public Class GetClassById(int id)
// {
// return (from cl in this.Classes
// where cl.ID == id
// select cl).SingleOrDefault();
// }

public Class GetClassByName(String name)
{
return (from cl in this.Classes
where cl.ID == id
where cl.Name == name
select cl).SingleOrDefault();
}

Expand Down
2 changes: 2 additions & 0 deletions StudentManager/Student.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace StudentManager
{
public class Student: Identity
{
[Identity.ID]
public string ID { get; set; }
public string Name { get; set; }

public string Address { get; set; }
Expand Down
1 change: 1 addition & 0 deletions StudentManager/StudentManager.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
<Compile Include="Tests\TestPersistence.cs" />
<Compile Include="XMLDatabase.cs" />
<Compile Include="Identity.cs" />
<Compile Include="TextInterface.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
10 changes: 4 additions & 6 deletions StudentManager/Tests/TestIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ public void TestStudent()
{
var a = new Student()
{
ID = 10
ID = "aoe"
};

var b = new Student()
{
ID = 5
ID = "aoed"
};

Assert.That(a.CompareTo(b) > 0);
Assert.False(a.Equals(b));
}

Expand All @@ -31,15 +30,14 @@ public void TestClass()
{
var a = new Class()
{
ID = 10
Name = "C1203L"
};

var b = new Class()
{
ID = 5
Name = "C1203F"
};

Assert.That(a.CompareTo(b) > 0);
Assert.False(a.Equals(b));
}
}
Expand Down
14 changes: 5 additions & 9 deletions StudentManager/Tests/TestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ class TestStudentManagement
private Manager m;
private Student trung = new Student()
{
ID = 10,
ID = "B01414",
Name = "Trung"
};
private Class c1203l = new Class()
{
ID = 3,
Name = "C1203L",
Teacher = "NhatNK"
};
Expand All @@ -29,11 +28,11 @@ public void Init() {

[Test]
public void TestGetStudentByID() {
Assert.Null(m.GetStudentById(10));
Assert.Null(m.GetStudentById("B01415"));

m.Students.Add(trung);
Assert.AreSame(trung, m.GetStudentById(10));
Assert.Null(m.GetStudentById(80));
Assert.AreSame(trung, m.GetStudentById("B01414"));
Assert.Null(m.GetStudentById(""));
}

[Test]
Expand All @@ -53,8 +52,7 @@ public void TestRegisterStudent() {
[Test]
public void TestChangeClassOfStudent() {
var bogusClass = new Class()
{
ID = 40,
{
Name = "Bogus"
};
m.Classes.Add(c1203l);
Expand All @@ -75,12 +73,10 @@ class TestClassAllocation
private Manager m;
private Class c1203l = new Class()
{
ID = 3,
Name = "C1203L"
};
private Class bogus = new Class()
{
ID = 4,
Name = "Bogus"
};

Expand Down
Loading