Baran Topal

Baran Topal


September 2020
M T W T F S S
« Feb    
 123456
78910111213
14151617181920
21222324252627
282930  

Categories


A C# TDD Example

baranbaran

 

 

Let’s see. I didn’t write a .NET post for a long time, and I am posting a fun project which is a Robot Cleaner that I had implemented in C#.NET.

Although this is a trivial project, it requires a simple understanding of TDD and at that time, my TDD experience in .NET was limited.

Now, let’s check how one can create a test project in .NET:

Simple, eh? Note that above is a simple test project creation and below is showing where you can find your test cases.

You can simply right click on a case and run it and see what happens as follows. Note that the running will yield, a pass or fail according to the test conditions.

Now, let’s check for the domain and the needs of this domain:

Robot Cleaner

Background

When you have a lot of people working in an office it can get dirty quite quickly if you’re not careful.  However, cleaning staff are expensive. To save money on cleaning staff the best solution was deemed to be the creation of an automatic cleaning robot that cleans the office at night.

Assignment

Your assignment is to build a prototype of this robot.  The assignment is designed to be as simple as possible.   The robot will, once given some instructions (shown below as input), run on its own without any human interference.  In the morning we can ask the robot to report how many unique places in the office it has cleaned.

Input and Output Criteria

Special Notes

The Output

The output of your program should be a number u, which represents the number of unique places in the office that were cleaned. The output of the number u should be prefixed by 1=> Cleaned: 1, (excluding the quotes).

Example input:

10 22 E2 N1

Example output:

=> Cleaned: 4

Now, let’s check for the trivial implemetation but first, couple of word regarding TDD:

TDD designates Test Driven Development in a such way that you code for testing reasons. This effectively means you are designing your algorithm in a test driven approach. You can read lots of papers about it, but this post will give you a faster recognition of what I am doing.

There are lots of testing approaches and I may mention those later on another post. Now, let’s focus on the coding style. Note that, the code may seem overcommented. I did the commenting since I don’t want to populate a confusion here in the post.

This project is implemented in VS2010-Ultimate. You can run this project also in VS2012 without a glitch, but to run this in VS2008 or VS2005, you cannot simply run it because while loading the project in those environments, it will pop up error, but there is a simple way to fix this, all you need is to change the version of the VS in Foo.sln where Foo is the solution name. In the following sln file, all you need to change is the first line version, Microsoft Visual Studio Solution File, Format Version 11.00 to 10.00 or 9.00.

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobotCleaner.Application", "RobotCleaner.Application\RobotCleaner.Application.csproj", "{96BF0E94-A85E-4AEC-AA44-0777D742DF00}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "com.cint.RobotCleaner", "com.cint.RobotCleaner", "{C1D1EA87-A74F-491B-8C42-35562D33A8B6}"
ProjectSection(SolutionItems) = preProject
..\..\..\..\..\Instructions .pdf = ..\..\..\..\..\Instructions .pdf
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobotCleaner.Test", "RobotCleaner.Test\RobotCleaner.Test.csproj", "{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9AC17769-BD0A-4DB7-A828-2FC47533314B}"
ProjectSection(SolutionItems) = preProject
Local.testsettings = Local.testsettings
RobotCleaner.vsmdi = RobotCleaner.vsmdi
TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobotCleaner.Entity", "RobotCleaner.Entity\RobotCleaner.Entity.csproj", "{FBAE4384-2EC3-4204-B80A-47B321BF68E2}"
EndProject
Global
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = RobotCleaner.vsmdi
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Debug|Any CPU.ActiveCfg = Debug|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Debug|Mixed Platforms.Build.0 = Debug|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Debug|x86.ActiveCfg = Debug|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Debug|x86.Build.0 = Debug|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Release|Any CPU.ActiveCfg = Release|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Release|Mixed Platforms.ActiveCfg = Release|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Release|Mixed Platforms.Build.0 = Release|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Release|x86.ActiveCfg = Release|x86
{96BF0E94-A85E-4AEC-AA44-0777D742DF00}.Release|x86.Build.0 = Release|x86
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Debug|x86.ActiveCfg = Debug|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Release|Any CPU.Build.0 = Release|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C}.Release|x86.ActiveCfg = Release|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Debug|x86.ActiveCfg = Debug|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Release|Any CPU.Build.0 = Release|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{FBAE4384-2EC3-4204-B80A-47B321BF68E2}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{96BF0E94-A85E-4AEC-AA44-0777D742DF00} = {C1D1EA87-A74F-491B-8C42-35562D33A8B6}
{F606FDEA-9BB4-4626-83DC-C1ED4A29643C} = {C1D1EA87-A74F-491B-8C42-35562D33A8B6}
{9AC17769-BD0A-4DB7-A828-2FC47533314B} = {C1D1EA87-A74F-491B-8C42-35562D33A8B6}
{FBAE4384-2EC3-4204-B80A-47B321BF68E2} = {C1D1EA87-A74F-491B-8C42-35562D33A8B6}
EndGlobalSection
EndGlobal

Now, let’s aim for our need. There may be lots of way, but I prefer more structured way in every of my implementations. In this solution, as you can see, there are 3 projects, all of which are in a folder named as com.cint.RobotCleaner

/* 
 * * * * * * * * * * * * * * * * * * * *
 * Company: CINT                       *            
 * Assignment: Robot Cleaner           *
 * Deadline: 2012-02-11                *
 * Programmer: Baran Topal             *
 * Solution name: Cint.RobotCleaner    *
 * Folder name: com.cint.RobotCleaner  *
 * Project name: RobotCleaner.Entity   *
 * File name: WorkItem.cs              *
 *                                     *      
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *	                                                                                         *
 *  LICENSE: This source file is subject to have the protection of GNU General               *
 *	Public License. You can distribute the code freely but storing this license information. *
 *	Contact Baran Topal if you have any questions. jazzIIIlove@gmail.com || topal@kth.se     *
 *	                                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//entity to store the workitem and position in given coordinates
namespace RobotCleaner.Entity
{

    ///
 /// WorkItem class dealing with the places visited, /// current position of the robot and /// instructions given in the plane limits /// 

public class WorkItem { #region member variables ///

/// a 2-D matrix which will be used as location where the robot /// can move around. It’s initialized as false. /// A single point plane[x, y] is false if it’s not visited yet, true otherwise ///

 

public bool[,] Plane; ///

/// current position of the given robot ///

 

public Position CurrentPosition; ///

/// number of places visited by the robot ///

 

public int PlacesVisited; ///

/// list of string inputs carrying the instructions ///

 

public ListInstructions; #endregion member variables #region constructors ///

/// Default constructor to initialize the work item ///

 

/// Important note: /// clr limit: 2 147 483 648 || 2GB = 2 x 1024 x 1024 x 1024 /// assignment array size: 40 000 000 000 || 200000 x 200000 /// I have to go for a simplification for the need and i omit one ‘0’ in each dimension. public WorkItem() { Instructions = new List(); Plane = new bool[20001, 20001]; PlacesVisited = 0; } ///

/// Constructor to initialize a position object with incoming startingPosition and list of instructions ///

 

//////public WorkItem(Position startingPosition, List instructions) { Plane = new bool[20001, 20001]; Move(startingPosition); Instructions = instructions; } #endregion constructors #region member methods ///

/// Checks whether the robot can go to the given position or not /// The boundary is the 2-D plane boundaries. ///

 

///position to be checked /// True if the position is inside the plane, false otherwise public static bool CanMove(Position position) { //return (position.X >= -10000 && position.X = -10000 && position.Y = 0 && position.X = 0 && position.Y

/// Moves toward the position. Updates the current position. /// If new position is already visited, the number of places visited is not increased. /// If new position is not visited, the number of places visited is increased. ///

 

///Position to move public void Move(Position position) { if (!PositionAlreadyVisited(position)) { PlacesVisited++; } CurrentPosition = position; } ///

/// Checks whether the given position is visited already or not ///

 

///Position to be checked /// True if the position is already visited, false otherwise public bool PositionAlreadyVisited(Position position) { if (Plane[position.X, position.Y]) return true; else { Plane[position.X, position.Y] = true; return false; } } ///

/// Follows instructions and returns places visited by the robot. ///

 

/// Places visited by the robotpublic int GetOutput() { FollowInstructions(); return PlacesVisited; } ///

/// Reads list of instructions. /// First, The number of instructions. /// Second, Sets the robot’s current position. /// And then, move the robot according to the instructions. ///

 

public void FollowInstructions() { Move(CurrentPosition); for (int i = 0; i < Instructions.Count; i++) MoveRobot(Instructions[i]); } ///

/// Gets the position by taking (0, 0) at the center of 2-D plane. /// In actual context, it’s +10000 from given string for the sake of array initialization. ///

 

///X and Y coordinates, e.g. “6 8” /// Position w.r.t. (0, 0) at center. public static Position GetPosition(string p) { //slitting input with the tokenizer char, ‘ ‘ string[] tokens = p.Split(‘ ‘); //initializing the Position object with the given splitted values return new Position((Int32.Parse(tokens[0]) + 10000), Int32.Parse(tokens[1]) + 10000); } ///

/// Gets the number of commands ///

 

///number of commands /// public static int GetNumberOfCommands(string c) { return Int32.Parse(c); } ///

/// Gets the instruction and moves the robot in /// a particular direction, e.g. N, S, E, W /// and in a particular step, e.g. Integer values ///

 

///private void MoveRobot(string instruction) { //slitting instruction with the tokenizer char, ‘ ‘ string[] tokens = instruction.Split(‘ ‘); //direction string direction = tokens[0]; //number of steps int steps = Int32.Parse(tokens[1]); switch (direction) { //Move north with the given number of steps case “N”: MoveNorth(steps); break; //Move south with the given number of steps case “S”: MoveSouth(steps); break; //Move east with the given number of steps case “E”: MoveEast(steps); break; //Move west with the given number of steps case “W”: MoveWest(steps); break; default: //None of above break; } } ///

/// Moves towards north with the given number of steps. /// If it cannot, then it returns. ///

 

///Number of steps private void MoveNorth(int steps) { //loop until the number of steps is reached for (int i = 0; i < steps; i++) { //New position Position position = new Position(CurrentPosition.X + 0, CurrentPosition.Y + 1); //Check whether it can move or not if (CanMove(position)) Move(position); else break; } } ///

/// Moves towards south with the given number of steps. /// If it cannot, then it returns. ///

 

///Number of steps private void MoveSouth(int steps) { //loop until the number of steps is reached for (int i = 0; i < steps; i++) { //New position Position position = new Position(CurrentPosition.X + 0, CurrentPosition.Y – 1); //Check whether it can move or not if (CanMove(position)) Move(position); else break; } } ///

/// Moves towards east with the given number of steps. /// If it cannot, then it returns. ///

 

///Number of steps private void MoveEast(int steps) { //loop until the number of steps is reached for (int i = 0; i < steps; i++) { //New position Position position = new Position(CurrentPosition.X + 1, CurrentPosition.Y + 0); //Check whether it can move or not if (CanMove(position)) Move(position); else break; } } ///

/// Moves towards west with the given number of steps. /// If it cannot, then it returns. ///

 

///Number of steps private void MoveWest(int steps) { //loop until the number of steps is reached for (int i = 0; i < steps; i++) { //New position Position position = new Position(CurrentPosition.X – 1, CurrentPosition.Y + 0); //Check whether it can move or not if (CanMove(position)) Move(position); else break; } } #endregion member methods } }

/* 
 * * * * * * * * * * * * * * * * * * * *
 * Company: CINT                       *            
 * Assignment: Robot Cleaner           *
 * Deadline: 2012-02-11                *
 * Programmer: Baran Topal             *
 * Solution name: Cint.RobotCleaner    *
 * Folder name: com.cint.RobotCleaner  *
 * Project name: RobotCleaner.Entity   *
 * File name: Position.cs              *
 *                                     *      
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *	                                                                                         *
 *  LICENSE: This source file is subject to have the protection of GNU General               *
 *	Public License. You can distribute the code freely but storing this license information. *
 *	Contact Baran Topal if you have any questions. jazzIIIlove@gmail.com || topal@kth.se     *
 *	                                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//entity to store the workitem and position in given coordinates
namespace RobotCleaner.Entity
{
    ///
 /// position class to store x, y member variables /// 

public class Position { #region member variables ///

/// variable storing x coordinate ///

 

private int x; ///

/// variable storing y coordinate ///

 

private int y; #endregion member variables #region accessors ///

/// accessor X to reach private variable x ///

 

public int X { get { return x; } set { x = value; } } ///

/// accessor Y to reach private variable y ///

 

public int Y { get { return y; } set { y = value; } } #endregion accessors #region constructors ///

/// Constructor to initialize a position object with incoming xPosition and yPosition variables ///

 

//////public Position(int xPosition, int yPosition) { x = xPosition; y = yPosition; } #endregion constructors } }

/* 
 * * * * * * * * * * * * * * * * * * * * * * *
 * Company: CINT                             *            
 * Assignment: Robot Cleaner                 *
 * Deadline: 2012-02-11                      *
 * Programmer: Baran Topal                   *
 * Solution name: Cint.RobotCleaner          *
 * Folder name: com.cint.RobotCleaner        *
 * Project name: RobotCleaner.Application    *
 * File name: Program.cs                     *
 *                                           *      
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *	                                                                                         *
 *  LICENSE: This source file is subject to have the protection of GNU General               *
 *	Public License. You can distribute the code freely but storing this license information. *
 *	Contact Baran Topal if you have any questions. jazzIIIlove@gmail.com || topal@kth.se     *
 *	                                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RobotCleaner.Entity;

//Robot cleaner console application main gate
namespace RobotCleaner
{
    ///
 /// Program to access to main gate /// 

class Program { #region methods ///

/// Main ///

 

///No cmd line argument expected static void Main(string[] args) { //Console.Write(“Enter the number of instructions: “); //user inputs the number of commands, e.g. 2 //int numberOfCommands = Int32.Parse(Console.ReadLine()); int numberOfCommands = WorkItem.GetNumberOfCommands(Console.ReadLine()); //Console.Write(“Enter the starting position: “); //user inputs the starting position for the robot, e.g. 10 22 Position startingPosition = WorkItem.GetPosition(Console.ReadLine()); //list to store the instructions given by the user List instructions = new List(); //Console.WriteLine(“Enter the instructions: “); //loop over the instructions and add each of them to the list, until the numberOfCommand is reached for (int i = 0; i < numberOfCommands; i++) { //Console.Write((i + 1) + “: “); instructions.Add(Console.ReadLine()); } //passing starting position and instructions of the robot WorkItem workItem = new WorkItem(startingPosition, instructions); //output after the process int output = workItem.GetOutput(); //Console.WriteLine(“Cleaned (Start Position counted): {0}”, output); Console.WriteLine(“=> Cleaned: {0}”, output); //output–; //Console.WriteLine(“Cleaned (Start Position neglected): {0}”, output); Console.ReadLine(); } #endregion methods } }

/* 
 * * * * * * * * * * * * * * * * * * * *
 * Company: CINT                       *            
 * Assignment: Robot Cleaner           *
 * Deadline: 2012-02-11                *
 * Programmer: Baran Topal             *
 * Solution name: Cint.RobotCleaner    *
 * Folder name: com.cint.RobotCleaner  *
 * Project name: RobotCleaner.Test     *
 * File name: PositionTest.cs          *
 *                                     *      
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *	                                                                                         *
 *  LICENSE: This source file is subject to have the protection of GNU General               *
 *	Public License. You can distribute the code freely but storing this license information. *
 *	Contact Baran Topal if you have any questions. jazzIIIlove@gmail.com || topal@kth.se     *
 *	                                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RobotCleaner.Entity;

//Test Project for Position and WorkItem
namespace RobotCleaner.Test
{
    ///
 /// This is a test class for PositionTest and is intended /// to contain all PositionTest for unit tests. /// 

[TestClass] public class PositionTest { #region member variables private TestContext testContextInstance; #endregion member variables #region constructors ///

/// Default constructor for PositionTest object ///

 

public PositionTest() { // // TODO: Add constructor logic here // } #endregion constructors #region accessors ///

/// Gets or sets the test context which provides /// information about and functionality for the current test run. ///

 

public TestContext TestContext { get { return testContextInstance; } set { testContextInstance = value; } } #endregion accessors #region member functions ///

/// Test for setting x position to 0 via constructor ///

 

[TestMethod] public void Set_X_Position_0_By_Constructor() { //Arrange int xPosition = 0; int yPosition = 0; //target position object Position target = new Position(xPosition, yPosition); //Actual var actual = target.X; //Assert Assert.AreEqual(xPosition, actual); } ///

/// Test for setting y position to 0 via constructor ///

 

[TestMethod] public void Set_Y_Position_0_By_Constructor() { //Arrange int xPosition = 0; int yPosition = 0; //target position object Position target = new Position(xPosition, yPosition); //Actual var actual = target.Y; //Assert Assert.AreEqual(yPosition, actual); } ///

/// Test for setting x position to a value via constructor ///

 

[TestMethod] public void Set_X_Position_By_Constructor() { //Arrange int xPosition = 15; int yPosition = 0; //target position object Position target = new Position(xPosition, yPosition); //Actual var actual = target.X; //Assert Assert.AreEqual(xPosition, actual); } ///

/// Test for setting y position to value via constructor ///

 

[TestMethod] public void Set_Y_Position_By_Constructor() { //Arrange int xPosition = 0; int yPosition = 15; //target position object Position target = new Position(xPosition, yPosition); //Actual var actual = target.Y; //Assert Assert.AreEqual(yPosition, actual); } #endregion member functions } }

/* 
 * * * * * * * * * * * * * * * * * * * *
 * Company: CINT                       *            
 * Assignment: Robot Cleaner           *
 * Deadline: 2012-02-11                *
 * Programmer: Baran Topal             *
 * Solution name: Cint.RobotCleaner    *
 * Folder name: com.cint.RobotCleaner  *
 * Project name: RobotCleaner.Test     *
 * File name: PositionTest.cs          *
 *                                     *      
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *	                                                                                         *
 *  LICENSE: This source file is subject to have the protection of GNU General               *
 *	Public License. You can distribute the code freely but storing this license information. *
 *	Contact Baran Topal if you have any questions. jazzIIIlove@gmail.com || topal@kth.se     *
 *	                                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RobotCleaner.Entity;

//Test Project for Position and WorkItem
namespace RobotCleaner.Test
{
    ///
 /// This is a test class for WorkItemTest and is intended /// to contain all WorkItemTest unit tests. /// 

[TestClass] public class WorkItemTest { #region member functions ///

/// Test for WorkItem object with default constructor inputs. /// When a new WorkItem object is created, all the items are set accordingly. ///

 

[TestMethod] public void WorkItem_Constructor_Sets_Everything() { //Arrange var placesVisited = 0; var instructionsCount = 0; //Actual var target = new WorkItem(); //Assert Assert.AreEqual(placesVisited, target.PlacesVisited); Assert.AreEqual(instructionsCount, target.Instructions.Count); } ///

/// Test for WorkItem object with non-default constructor inputs. /// When constructor with argument is invoked, current position is set and number of visited places is incremented. /// The current position and the instructions given comply in the assignment document provided. ///

 

[TestMethod] public void WorkItem_Constructor_With_Arguments() { //Arrange var startingPosition = WorkItem.GetPosition(“5 5”); Listinstructions = new List(); instructions.Add(“S 2”); var visitedPlaces = 1; //Actual var target = new WorkItem(startingPosition, instructions); //Assert Assert.AreEqual(startingPosition, target.CurrentPosition); Assert.AreEqual(instructions.Count, target.Instructions.Count); Assert.AreEqual(visitedPlaces, target.PlacesVisited); } ///

/// Test for WorkItem object by setting and getting its position values. /// In this unit test, a WorkItem object is initialized and set its current position to a position. /// This test will pass if the current position returns the same position which is assigned it. ///

 

[TestMethod] public void CurrentPosition_Set_And_Get_Returns_Same() { //Arrange var expected = new Position(0, 0); var target = new WorkItem(); //Actual target.CurrentPosition = expected; var actual = target.CurrentPosition; //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object setting its instruction values. /// In this unit test, a WorkItem object is initialized and set its instruction list with a instruction set. /// This test will pass if the instructions returns the same instruction set which is assigned it. ///

 

[TestMethod] public void Instructions_Set_And_Get_Returns_Same() { //Arrange var expected = new List(); var target = new WorkItem(); //Actual target.Instructions = expected; var actual = target.Instructions; //Assert Assert.AreEqual(expected, actual); } ///

/// Test for how many places visited by the robot. /// In this function, a custom list of instructions in which robot visits 2 places is given. /// Expected output should be 3 as the starting position is also counted as a visited place. ///

 

[TestMethod] public void GetOutput_Returns_Places_Visited() { //Arrange var expected = 3; var instructions = new List(); var position = new Position(5, 10); instructions.Add(“N 2”); var target = new WorkItem(position, instructions); //Actual var actual = target.GetOutput(); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for following instruction (incoming instruction) to the robot. /// FollowInstructions set the current position by reading second instruction from the list. /// After FollowInstruction function is invoked, it’s expected that the current position shall be the same given. ///

 

[TestMethod] public void Follow_Instructions_Set_CurrentPosition() { //Arrange var expected = new Position(105, 110); var instructions = new List(); instructions.Add(“105 110”); var target = new WorkItem(expected, instructions); //Actual target.FollowInstructions(); var actual = target.CurrentPosition; //Assert Assert.AreEqual(expected.X, actual.X); Assert.AreEqual(expected.Y, actual.Y); } ///

/// Test for checking for the current position of the robot. /// When current position is set, place visited is incremented by one. ///

 

[TestMethod] public void Follow_Instructions_Incremets_PlacesVisited() { //Arrange var expected = 1; var position = new Position(105, 110); var instructions = new List(); instructions.Add(“105 110”); var target = new WorkItem(position, instructions); //Actual target.FollowInstructions(); var actual = target.PlacesVisited; //Assert Assert.AreEqual(expected, actual); } ///

/// Test for starting position according to the zero base /// Starting position given is relative to the 2-D plane having (0,0) at the center and (-100, 100) as their range in both x and y axis. /// But the plane, which is created has (0,0) at top left corner. /// It is a [201, 201] array. So there is an increment of 100 to both x and y of starting position. /// In this test 5,10 is given as input which means that they will be at 105,110 in the 2-D plane of the context. ///

 

[TestMethod] public void GetPosition_Returns_Position_According_To_ZeroBase() { //Arrange var expected = new Position(10105, 10110); //Actual var actual = WorkItem.GetPosition(“105 110”); //Assert Assert.AreEqual(expected.X, actual.X); Assert.AreEqual(expected.Y, actual.Y); } ///

/// Test for WorkItem to check whether the integer input value is assessed as it’s given ///

 

[TestMethod] public void GetInput_NumberOfCommands() { //Arrange var expected = 4; //Actual var actual = WorkItem.GetNumberOfCommands(“4”); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem to check whether the the integer input value exceeds the maximum input number ///

 

[TestMethod] public void Exceed_NumberOfCommands() { //Arrange bool notExceed = true; var expected = false; if (WorkItem.GetNumberOfCommands(“10001”) > 10000) { notExceed = false; } //Actual var actual = notExceed; //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether it can move or not. /// If the given position is inside the plane, the robot can move to that position, true case. ///

 

[TestMethod] public void CanMove_Returns_True() { //Arrange var expected = true; var position = new Position(100, 100); //Actual var actual = WorkItem.CanMove(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether it can move or not. /// If the given position is not inside the plane, the robot can’t move to that position, false case. ///

 

[TestMethod] public void CanMove_Returns_False_For_Negative_X() { //Arrange var expected = false; var position = new Position(-10001, 0); //Actual var actual = WorkItem.CanMove(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether it can move or not. /// If the given position is not inside the plane, the robot can’t move to that position, false case. ///

 

[TestMethod] public void CanMove_Returns_False_For_Negative_Y() { //Arrange var expected = false; var position = new Position(0, -10001); //Actual var actual = WorkItem.CanMove(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether it can move or not. /// If the given position is not inside the plane, the robot can’t move to that position, false case. ///

 

[TestMethod] public void CanMove_Returns_False_For_Negative_X_And_Y() { //Arrange var expected = false; var position = new Position(-10001, -10001); //Actual var actual = WorkItem.CanMove(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether it can move or not. /// If the given position is not inside the plane, the robot can’t move to that position, false case. ///

 

[TestMethod] public void CanMove_Returns_False_For_Greater_X() { //Arrange var expected = false; var position = new Position(20001, 0); //Actual var actual = WorkItem.CanMove(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether it can move or not. /// If the given position is not inside the plane, the robot can’t move to that position, false case. ///

 

[TestMethod] public void CanMove_Returns_False_For_Greater_Y() { //Arrange var expected = false; var position = new Position(0, 20001); //Actual var actual = WorkItem.CanMove(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether it can move or not. /// If the given position is not inside the plane, the robot can’t move to that position, false case. ///

 

[TestMethod] public void CanMove_Returns_False_For_Greater_X_And_Y() { //Arrange var expected = false; var position = new Position(20001, 20001); //Actual var actual = WorkItem.CanMove(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether it visited an unvisited place. /// If a place is not visited before then the number of visited place will be incremented. In PostitionAlreadyVisited(), /// a postion has been given and it’s expected that it will return false if it has not been visited before. So here, we setup /// that position 5,5 is not visited before by making plane[5, 5] false. /// Now function should return false to pass. ///

 

[TestMethod] public void PositionAlreadyVisited_Returns_False_For_Unvisited_Place() { //Arrange var expected = false; var position = new Position(5, 5); var target = new WorkItem(); target.Plane[5, 5] = false; //Actual var actual = target.PositionAlreadyVisited(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether the unvisited place is true. /// If a position is not visited before then PositionAlreadyVisited()’s state will change to true. So we expect, /// that a place which is not visited will be true when function is called. ///

 

[TestMethod] public void PositionAlreadyVisited_Sets_PositionVisited_If_Not_Visited() { //Arrange var expected = true; var position = new Position(5, 5); var target = new WorkItem(); target.PositionAlreadyVisited(position); //Actual var actual = target.Plane[5, 5]; //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem object whether the postion is already visited /// If a position is visited then the function returns true. In this case, there won’t be an increment of visitedPlaces. /// We setup position 5,5 as visited. Now test will pass if function returns true. ///

 

[TestMethod] public void PositionAlreadyVisited_Returns_True_For_Visited_Place() { //Arrange var expected = true; var position = new Position(5, 5); var target = new WorkItem(); target.Plane[5, 5] = true; //Actual var actual = target.PositionAlreadyVisited(position); //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem to set new position /// After a move function, current position will be changed. So in this case, the move function is invoked with a position. /// Now, it’s expected that after the function invocation, currentPosition should be changed to the position we give to the function. ///

 

[TestMethod] public void Move_Sets_New_CurrentPosition() { //Arrange var expected = new Position(5, 5); var target = new WorkItem(); //Actual target.Move(expected); var actual = target.CurrentPosition; //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem to increment the places visited after the move. /// If the place is not visited before, then, after the move function, visitedPlaces should be increment by one. /// In this case, a position is given to move function which is not visited before. /// And, it’s expected that placesVisited will be incremented by one. ///

 

[TestMethod] public void Move_Increments_PlaceVisited_If_Position_Is_Not_Visited() { //Arrange var position = new Position(5, 5); var target = new WorkItem(); target.PlacesVisited = 0; var expected = target.PlacesVisited + 1; //Actual target.Move(position); var actual = target.PlacesVisited; //Assert Assert.AreEqual(expected, actual); } ///

/// Test for WorkItem -not- to increment the places visited after the move. /// If the place is visited before, then, after the move function, visitedPlaces should -not- be increment by one. /// In this case, a position is given to move function which is already visited before. /// And, it’s expected that placesVisited will remain same after the function invocation. ///

 

public void Move_Dont_Increment_PlaceVisited_If_Position_Is_Visited() { //Arrange var position = new Position(5, 5); var target = new WorkItem(); target.PlacesVisited = 1; var expected = target.PlacesVisited; target.Plane[5, 5] = true; //Actual target.Move(position); var actual = target.PlacesVisited; //Assert Assert.AreEqual(expected, actual); } #endregion member functions } }

I also provide this in the public dropbox link:

https://dl.dropbox.com/u/1327371/RobotCleaner.rar

Comments 0
There are currently no comments.