Browse Source

implemented FileImporter tests and added access methods for testing to FileImporter (import method invocation with String[] instead of file path) and Form1 (a method to create a new canvas on the left side and add and draw a picture there and an universal getter method for use by all tests which need encapsulated data, returning ALL global variables of Form1 in an Object array in the order of their definition)

Vincenz Mechler 5 years ago
parent
commit
afb64d3735

+ 3 - 0
SketchAssistant/SketchAssistant.Tests/SketchAssistant.Tests.csproj

@@ -48,6 +48,9 @@
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Drawing" />
+    <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
+    </Reference>
     <Reference Include="System.Windows.Forms" />
   </ItemGroup>
   <ItemGroup>

+ 54 - 19
SketchAssistant/SketchAssistant.Tests/UnitTest1.cs

@@ -274,7 +274,6 @@ namespace Tests
         }
     }
 
-    /*
     [TestClass]
     public class FileImporterTests
     {
@@ -290,22 +289,23 @@ namespace Tests
             List<String> file = new List<string>();
             file.Add("drawing");
             file.Add("300x200");
-            for(int i = 0; i < xCoordinates.Length - 2; i++)
+            for (int i = 0; i < xCoordinates.Length - 2; i += 3)
             {
                 file.Add("line");
-                file.Add(xCoordinates[i - 2] + ";" + yCoordinates[i - 2]);
-                file.Add(xCoordinates[i - 1] + ";" + yCoordinates[i - 1]);
                 file.Add(xCoordinates[i] + ";" + yCoordinates[i]);
+                file.Add(xCoordinates[i + 1] + ";" + yCoordinates[i + 1]);
+                file.Add(xCoordinates[i + 2] + ";" + yCoordinates[i + 2]);
                 file.Add("endline");
             }
             file.Add("enddrawing");
 
-            uut.ParseISADInput(file.ToArray());
+            (int, int, List<Line>) values = uut.ParseISADInputForTesting(file.ToArray());
+            program.CreateCanvasAndSetPictureForTesting(values.Item1, values.Item2, values.Item3);
 
-            Line[] drawing = program.templatePicture.ToArray();
+            Line[] drawing = GetLeftImage(program).ToArray();
 
             Assert.AreEqual(xCoordinates.Length / 3, drawing.Length);
-            for(int i = 0; i < xCoordinates.Length - 2; i += 3)
+            for (int i = 0; i < xCoordinates.Length - 2; i += 3)
             {
                 Point[] currentLine = drawing[i / 3].GetPoints().ToArray();
                 Assert.AreEqual(3, currentLine.Length);
@@ -317,22 +317,57 @@ namespace Tests
         }
 
         [DataTestMethod]
-
-        public void ParseISADInputSuccessfulTest(String[] file)
+        [DataRow(new String[] {})]
+        [DataRow(new String[] { "begindrawing", "300x300", "line", "50;50", "100;50", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300;300", "line", "50;50", "100;50", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "30.5x300", "line", "50;50", "100;50", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "line", "50;50", "100;50", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "beginline", "50;50", "100;50", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "line", "500;50", "100;50", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "line", "50x50", "100;50", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "line", "50", "100", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "line", "50;50", "line", "endline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "line", "50;50", "100;50", "stopline", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "line", "50;50", "100;50", "enddrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "line", "50;50", "100;50", "endline", "endrawing" })]
+        [DataRow(new String[] { "drawing", "300x300", "line", "50;50", "100;50", "endline" })]
+        public void ParseISADInputExceptionTest(String[] file)
         {
+            bool exceptionThrown = false;
             Form1 program = new Form1();
             FileImporter uut = new SketchAssistant.FileImporter(program);
+            //check that left image initially is uninitialized
+            Assert.IsNull(GetLeftImage(program));
+            //initialize left image with a valid isad drawing
+            (int, int, List<Line>) values = uut.ParseISADInputForTesting(new string[] { "drawing", "300x205", "line", "40;40", "140;140", "endline", "enddrawing" });
+            program.CreateCanvasAndSetPictureForTesting(values.Item1, values.Item2, values.Item3);
+            //save left image for later comparison
+            List<Line> oldLeftImage = GetLeftImage(program);
+            try
+            {
+                //try to initialize the left image with an invalid isad drawing
+                (int, int, List<Line>) values1 = uut.ParseISADInputForTesting(file);
+                program.CreateCanvasAndSetPictureForTesting(values1.Item1, values1.Item2, values1.Item3);
+            }
+            catch(FileImporterException ex)
+            {
+                //save the occurence of an exception
+                exceptionThrown = true;
+            }
+            //check that an exception has been thrown
+            Assert.IsTrue(exceptionThrown);
+            //check that the left image has not been changed by the failed image import
+            Assert.AreEqual(oldLeftImage, GetLeftImage(program));
+        }
 
-            Assert.IsNull(program.templatePicture);
-
-            uut.ParseISADInput(new string[] {"drawing", "300x205", "line", "40;40", "140;140", "endline", );
-
-            List<Line> oldTemplatePicture = program.templatePicture;
-
-            uut.ParseISADInput(file);
-
-            Assert.AreEqual(oldTemplatePicture, program.templatePicture);
+        /// <summary>
+        /// local helper method retrieving the left image from a Form1 instance
+        /// </summary>
+        /// <returns>the left image of the given Form1 instance</returns>
+        private List<Line> GetLeftImage(Form1 program)
+        {
+            //cast is save as long as Form1#GetAllVariables() is conform to its contract
+            return (List<Line>) program.GetAllVariables()[4];
         }
     }
-    */
 }

+ 1 - 0
SketchAssistant/SketchAssistant.Tests/packages.config

@@ -2,4 +2,5 @@
 <packages>
   <package id="MSTest.TestAdapter" version="1.4.0" targetFramework="net461" />
   <package id="MSTest.TestFramework" version="1.4.0" targetFramework="net461" />
+  <package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />
 </packages>

+ 34 - 6
SketchAssistant/SketchAssistant/FileImporter.cs

@@ -22,14 +22,22 @@ namespace SketchAssistant
         }
 
         /// <summary>
-        /// parses a drawing consisting of line objects, given in the application specific .isad format
+        /// parses a drawing consisting of line objects, given as a file in the application specific .isad format
         /// </summary>
         /// <param name="fileName">the path of the input file</param>
         /// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
-        public (int, int, List<Line>) ParseISADInput(String fileName)
+        public (int, int, List<Line>) ParseISADInputFile(String fileName)
         {
+            return ParseISADInput(System.IO.File.ReadAllLines(fileName));
+        }
 
-            String[] allLines = System.IO.File.ReadAllLines(fileName);
+        /// <summary>
+        /// parses a drawing consisting of line objects, given as the content of a .isad file, seperated into lines
+        /// </summary>
+        /// <param name="allLines">an array holding all lines of the input file</param>
+        /// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
+        private (int, int, List<Line>) ParseISADInput(String[] allLines)
+        {
 
             if (allLines.Length == 0)
             {
@@ -50,6 +58,8 @@ namespace SketchAssistant
             return (dimensions.Item1, dimensions.Item2, picture);
         }
 
+
+
         /// <summary>
         /// parses the first two lines of an input file in .isad format
         /// </summary>
@@ -59,7 +69,7 @@ namespace SketchAssistant
         {
             int width;
             int height;
-            if (!(allLines.Length > 1) || !Regex.Match(allLines[1], @"(\d?\d*x?\d?\d*?)?", RegexOptions.None).Success)
+            if (!(allLines.Length > 1) || !Regex.Match(allLines[1], @"^\d+x?\d+$", RegexOptions.None).Success)
             {
                 throw new FileImporterException("invalid or missing canvas size definition", "format: [width]x[heigth]", 2);
             }
@@ -85,6 +95,8 @@ namespace SketchAssistant
             //number of the line currently being parsed, enumeration starting at 0, body starts at the third line, therefore lin number 2
             int i = 2;
             //parse 'line' token and complete line definition
+            int lineStartPointer = i;
+            //holds the line number of the next expected beginning of a line definition, or of the enddrawing token
             while (lineStartString.Equals(allLines[i]))
             {
                 //start parsing next line
@@ -97,7 +109,7 @@ namespace SketchAssistant
                         throw new FileImporterException("unterminated line definition", null, (i + 1));
                     }
                     //parse single point definition
-                    if (!Regex.Match(allLines[i], @"(\d?\d*;?\d?\d*?)?", RegexOptions.None).Success)
+                    if (!Regex.Match(allLines[i], @"^\d+;\d+$", RegexOptions.None).Success)
                     {
                         throw new FileImporterException("invalid Point definition: wrong format", "format: [xCoordinate];[yCoordinate]", (i + 1) );
                     }
@@ -117,11 +129,27 @@ namespace SketchAssistant
                 i++;
                 //add line to drawing
                 drawing.Add(new Line(newLine));
+                //update lineStartPointer to the presumable start of the next line
+                lineStartPointer = i;
+            }
+            //check if end of body is reached after there are no more line definitions
+            if(i != allLines.Length - 1)
+            {
+                throw new FileImporterException("missing or invalid line definition token", "line definitions start with the 'line' token", (i + 1));
             }
-
             //return parsed picture
             return drawing;
         }
 
+        /// <summary>
+        /// connection point for testing use only: calls ParseISADInput(String[] allLines) and directly passes the given argument (effectively bypassing the File Input functionality)
+        /// </summary>
+        /// <param name="allLines">an array holding all lines of the input file</param>
+        /// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
+        public (int, int, List<Line>) ParseISADInputForTesting(String[] allLines)
+        {
+            return ParseISADInput(allLines);
+        }
+
     }
 }

+ 1 - 1
SketchAssistant/SketchAssistant/FileImporterException.cs

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
 
 namespace SketchAssistant
 {
-    class FileImporterException : Exception
+    public class FileImporterException : Exception
     {
         /// <summary>
         /// the clean and formatted message to show to the user

+ 32 - 9
SketchAssistant/SketchAssistant/Form1.cs

@@ -27,6 +27,8 @@ namespace SketchAssistant
         /*** CLASS VARIABLES START HERE ***/
         /**********************************/
 
+        //important: add new variables only at the end of the list to keep the order of definition consistent with the order in which they are returned by GetAllVariables()
+
         /// <summary>
         /// Different Program States
         /// </summary>
@@ -47,7 +49,7 @@ namespace SketchAssistant
         /// <summary>
         /// Dialog to select a file.
         /// </summary>
-        OpenFileDialog openFileDialogLeft = new OpenFileDialog();
+        OpenFileDialog openFileDialog = new OpenFileDialog();
         /// <summary>
         /// Image loaded on the left
         /// </summary>
@@ -123,11 +125,11 @@ namespace SketchAssistant
         //Load button, will open an OpenFileDialog
         private void loadToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            openFileDialogLeft.Filter = "Image|*.jpg;*.png;*.jpeg";
-            if(openFileDialogLeft.ShowDialog() == DialogResult.OK)
+            openFileDialog.Filter = "Image|*.jpg;*.png;*.jpeg";
+            if(openFileDialog.ShowDialog() == DialogResult.OK)
             {
-                toolStripLoadStatus.Text = openFileDialogLeft.SafeFileName;
-                leftImage = Image.FromFile(openFileDialogLeft.FileName);
+                toolStripLoadStatus.Text = openFileDialog.SafeFileName;
+                leftImage = Image.FromFile(openFileDialog.FileName);
                 pictureBoxLeft.Image = leftImage;
                 //Refresh the left image box when the content is changed
                 this.Refresh();
@@ -140,13 +142,13 @@ namespace SketchAssistant
         /// </summary>
         private void examplePictureToolStripMenuItem_Click(object sender, EventArgs e)
         {
-            openFileDialogLeft.Filter = "Interactive Sketch-Assistant Drawing|*.isad";
-            if (openFileDialogLeft.ShowDialog() == DialogResult.OK)
+            openFileDialog.Filter = "Interactive Sketch-Assistant Drawing|*.isad";
+            if (openFileDialog.ShowDialog() == DialogResult.OK)
             {
-                toolStripLoadStatus.Text = openFileDialogLeft.SafeFileName;
+                toolStripLoadStatus.Text = openFileDialog.SafeFileName;
                 try
                 {
-                    (int, int, List<Line>) values = fileImporter.ParseISADInput(openFileDialogLeft.FileName);
+                    (int, int, List<Line>) values = fileImporter.ParseISADInputFile(openFileDialog.FileName);
                     DrawEmptyCanvasLeft(values.Item1, values.Item2);
                     BindAndDrawLeftImage(values.Item3);
                     this.Refresh();
@@ -595,6 +597,27 @@ namespace SketchAssistant
             MessageBox.Show(message);
         }
 
+        /// <summary>
+        /// returns all instance variables in the order of their definition for testing
+        /// </summary>
+        /// <returns>all instance variables in the order of their definition</returns>
+        public Object[]/*(ProgramState, FileImporter, OpenFileDialog, Image, List<Line>, Image, List<Point>, List<Tuple<bool, Line>>, bool, Point, Point, Queue<Point>, Graphics, bool[,], HashSet<int>[,], uint, ActionHistory)*/ GetAllVariables()
+        {
+            return new Object[] { currentState, fileImporter, openFileDialog, leftImage, leftLineList, rightImage, currentLine, rightLineList, mousePressed, currentCursorPosition, previousCursorPosition, cursorPositions, rightGraph, isFilledMatrix, linesMatrix, deletionSize, historyOfActions };
+        }
+
+        /// <summary>
+        /// public method wrapper for testing purposes, invoking DrawEmptyCanvas(...) and BindAndDrawLeftImage(...)
+        /// </summary>
+        /// <param name="width">width of the parsed image</param>
+        /// <param name="height">height of the parsed image</param>
+        /// <param name="newImage">the parsed image</param>
+        public void CreateCanvasAndSetPictureForTesting(int width, int height, List<Line> newImage)
+        {
+            DrawEmptyCanvasLeft(width, height);
+            BindAndDrawLeftImage(newImage);
+        }
+
 
     }
 }