Toby and the step backwards

Being passionate about anything can have its drawbacks; in my zeal to give inside-out development a shot, I completely disregarded a couple principles I hold dear. SRP? Out the window. Test-first code? Left by the side of the road. I do have a set of what I'd call acceptance tests that are 85% complete given the current understanding of the system which means it's time to start refactoring and writing more tests :)

The first thing that needs to happen is to move create / find project functionality into its own class. I'm actually going to build this one bottom-up for now using the same parameters that are in EDMSystem currently.

[TestFixture]
public class ProjectRepositoryFixture
{
[Test]
  public void OnCreationRepositoryIsEmpty()
{
    ProjectRepository repository = new ProjectRepository();

    int projectCount = repository.Count;

    Assert.Equal<int>(0, projectCount);
}

[Test]
  public void AddingProjectToRepositoryIncreasesCountByOne()
{
    ProjectRepository repository = new ProjectRepository();

repository.AddProject(0, "my first project");

    Assert.Equal<int>(1, repository.Count);
}

[Test]
  public void CanFindProjectByNumber()
{
    ProjectRepository repository = new ProjectRepository();
repository.AddProject(0, "my first project");

    Project foundProject = repository.Find(0);

    Assert.NotNull(foundProject);
    Assert.Equal<int>(0, foundProject.Number);
    Assert.Equal<string>("my first project", foundProject.Name);
}

[Test]
  public void CanFindProjectByName()
{
    ProjectRepository repository = new ProjectRepository();
repository.AddProject(0, "my first project");

    Project foundProject = repository.Find("my first project");

    Assert.NotNull(foundProject);
    Assert.Equal<int>(0, foundProject.Number);
    Assert.Equal<string>("my first project", foundProject.Name);
}

[Test]
  public void CanFindProjectByNumberWhenThereAreTwoProjectsInTheRepository()
{
    ProjectRepository repository = new ProjectRepository();
repository.AddProject(0, "my first project");
repository.AddProject(2, "my second project");

    Project foundProject = repository.Find(0);

    Assert.NotNull(foundProject);
    Assert.Equal<int>(0, foundProject.Number);
    Assert.Equal<string>("my first project", foundProject.Name);
}

[Test]
  public void CanFindProjectByNameWhenThereAreTwoProjectsInTheRepository()
{
    ProjectRepository repository = new ProjectRepository();
repository.AddProject(0, "my first project");
repository.AddProject(2, "my second project");

    Project foundProject = repository.Find("my first project");

    Assert.NotNull(foundProject);
    Assert.Equal<int>(0, foundProject.Number);
    Assert.Equal<string>("my first project", foundProject.Name);
}
}

public class ProjectRepository
{
  public ProjectRepository()
{
projectDictionary = new Dictionary<int, Project>();
projectDictionaryByName = new Dictionary<string, Project>();
}

  public int Count
{
    get { return projectDictionary.Count; }
}

  public void AddProject(int projectNumber, string projectName)
{
    Project project = new Project(
projectNumber, projectName, null);
projectDictionary.Add(projectNumber, project);
projectDictionaryByName.Add(projectName, project);

       return project;
}

  public Project Find(int projectNumber)
{
    return projectDictionary[projectNumber];
}

  public Project Find(string projectName)
{
    return projectDictionaryByName[projectName];
}

  private Dictionary<int, Project> projectDictionary;
  private Dictionary<string, Project> projectDictionaryByName;
}

There is a small problem. I'm passing in null for IUserService in the Project constructor. I'm not really too thrilled with that right now but these things tend to come out in the wash. The EDMSystem class looks like this:

public class EDMSystem : IUserService
{
  public EDMSystem()
{
projectRepository = new ProjectRepository();
}

  public UserType CurrentUser
{
    get { return currentUser; }
}

  public int ProjectCount
{
    get { return projectRepository.Count; }
}

  public void LoginAs(UserType userType)
{
currentUser = userType;
}

  public Project CreateProject(int projectNumber,
                               string projectName)
{
    return projectRepository.AddProject
(projectNumber, projectName);
}

  public Project FindProject(int projectNumber)
{
    return projectRepository.Find(projectNumber);
}

  public Project FindProject(string projectName)
{
    return projectRepository.Find(projectName);
}

  private UserType currentUser;
  private ProjectRepository projectRepository;
}

Of course not all the acceptance tests are passing (remember the IUserService is null), but that's OK for now. One step at a time :) I can see EDMSystem quickly going away .. where's my DI container when I want one ...