Tuesday, November 26, 2013

Enable MbUnit Tests within Resharper 7.1 and Higher

Introduction

It is not possible to run unit tests written with the MbUnit test framework from within Resharper 7.1 and higher. To allow you to run them using Resharper you have to install a plugin.

Download

Install

Unzip and place them inside the following folder:
C:\Program Files (x86)\JetBrains\ReSharper\v7.1\Bin\plugins\


References


Gallio : Automated Integration Tests Autocad

1.     Introduction

Gallio is a very flexible, and extensible testing framework usedto run tests against the code that depends on the AutoCAD API.

2.     Download

Get the lastest version of Gallio at http://www.gallio.org

3.     Extract Gallio

Extract the downloaded .zip file to any location on your computer.
Before you extract the ZIP file, be sure to check its properties and click “Unblock” if that option is available.

4.     Setup MSVS 2012 (Existing or new project)

Add References

·         acdbmgd.dll (Autocad)
·         acmgd.dll (Autocad)
·         Gallio.dll, MbUnit.dll (The default Gallio test runner looks for tests written in your DLL that use the MbUnit testing framework.)

Configuration

·         Make sure you set your target framework correctly
·         External References should be set to 'Copy Local'= false (otherwise netload assemblies won't work)

5.     Create Batch

Create a .bat file and add the following code to it:
SET GALLIO_RUNTIME_PATH=C:\Users\Mysth\Downloads\GallioBundle-3.4.14.0\bin\
"C:\Users\Mysth\Downloads\GallioBundle-3.4.14.0\bin\Gallio.Echo.exe" gallio.dll /r:AutoCAD
pause

Place the batch alongside the assembly containing the tests.

6.     Reports

Gallio can generate reports with the results of the tests run in either html format or xml format.
Add the following to the batch to auto generate reports :
SET GALLIO_RUNTIME_PATH=C:\Data\GallioBundle-3.4.14.0\bin
"C:\Data\GallioBundle-3.4.14.0\bin\Gallio.Echo.exe" BRail.InfraNet.IntegrationTests.Domain.dll /r:AutoCAD/rt:xml /rt:html
Pause
Example run on BRail.InfraNet.Domain assembly



7.     Example

For this example to work add an extra assembly BeDeveloped.Framework.AutoCad.dll to your project.



Create a Test Class where our tests will be written in.
publicclassTests
    {
        [Test]
publicvoidTestCircleEqual()
        {
var services = newActiveServices();

services.EntityService.CreateCircle(0, 0, 20);

var id = services.DocumentService.GetLast();
var circle = services.EntityService.GetEntity(id) asCircle;

if (circle != null)
            {
Assert.AreEqual(20, circle.Radius);
            }
        }

[Test]
publicvoidTestCircleNotEqual()
        {
var services = newActiveServices();

services.EntityService.CreateCircle(0, 0, 10);

var id = services.DocumentService.GetLast();
var circle = services.EntityService.GetEntity(id) asCircle;

if (circle != null)
            {
Assert.AreEqual(20, circle.Radius);
}
        }
    }



Build your project and run the previously configured .bat file. Gallio should launch Autocad, load all the necessary assemblies and execute all tests. Gallio will close Autocad once all tests are executed.  You should see the following test result.
One test passedone should have failed.



8.     Known Issues

System.NotSupportedException:
An attempt was made to load an assembly
from a network location which would have caused the assembly to be sandboxed in
previous versions of the .NET Framework. This release of the .NET Framework
does not enable CAS policy by default, so this load may be dangerous. If this
load is not intended to sandbox the assembly, please enable the
loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569
for more information.

Tuesday, October 8, 2013

Osmode Autocad Snaps SetVariable & GetVariable

Goal
  1. Keep track of current snaps.
  2. Set new snaps.
  3. Perform one or more actions.
  4. Restore initial snaps.
Usefull links



Class Diagram

C# Code
  • First, I create an enumeration to easily sum up multiple snaps.
    /// <summary>
    /// Integer. Initial value 4133. Saved in Registry.
    /// Sets running object snaps.
    /// The setting is stored as a bitcode using the sum of the following values.
    /// To specify more then one object snap, enter the sum of their values.
    /// </summary>
    public enum Snaps
    {
        None = 0,
        Endpoint = 1,
        Midpoint = 2,
        Center = 4,
        Node = 8,
        Quadrant = 16,
        Intersection = 32,
        Insertion = 64,
        Perpendicular = 128,
        Tangent = 256,
        Nearest = 512,
        ClearAll = 1024,
        ApparentIntersection = 2048,
        Extention = 4096,
        Parallel = 8192,
        TrackingLines = 16384
    }
  • My class will implement an interface
    public interface ISnapMode
    {
        int InitialSnapMode { get; }
        int CurrentSnapMode { get; }

        int GetSnapMode();
        void SetSnapMode(int mode);

        void SetInitialSnapMode();
    }
  • The actual class implementation of the ISnapMode Interface
/// <summary>
    ///     Class that will keep track of the initial snap mode when creating an instance of the class and sets the requested snap mode.
    ///     Sets the snapmode to it's original state when disposed.
    /// </summary>
    public class SnapMode : ISnapMode
    {
        #region Variables & Properties

        /// <summary>
        ///     Private Variable. Keeps track of the initial Snap Mode
        /// </summary>
        private readonly int _initialSnapMode;

        /// <summary>
        ///     Public Property. Get the initial Snap Mode before object initialization.
        /// </summary>
        public int InitialSnapMode
        {
            get { return _initialSnapMode; }
        }

        /// <summary>
        ///     Public Property. Get the current snap mode after changing the initial snap mode.
        /// </summary>
        public int CurrentSnapMode
        {
            get { return GetSnapMode(); }
        }

        #endregion

        #region Constructors

        /// <summary>
        ///     Protected default constructor. Initialize an instance of the object SnapMode.
        /// </summary>
        protected SnapMode()
        {
            _initialSnapMode = GetSnapMode();
        }

        /// <summary>
        ///     Overloaded constructor. Initialize an instance of the object SnapMode.
        /// </summary>
        /// <param name="snapTypes"></param>
        public SnapMode(IEnumerable<Snaps> snapTypes)
            : this()
        {
            //Only distinct snaps to calculate the sum of all snap mode bitcode values.
            SetSnapMode(CalculateSnapMode(snapTypes.Distinct()));
        }

        /// <summary>
        ///     Overloaded constructor. Initialize an instance of the object SnapMode.
        /// </summary>
        /// <param name="snap"></param>
        public SnapMode(Snaps snap)
            : this()
        {
            SetSnapMode(int.Parse(snap.ToString()));
        }

        /// <summary>
        ///     Overloaded constructor. Initialize an instance of the object SnapMode.
        /// </summary>
        /// <param name="snapMode">Integer. Requested snapmode. To specify more then one object snap, enter the sum of their values</param>
        public SnapMode(int snapMode)
        {
            SetSnapMode(snapMode);
        }

        #endregion

        #region Implementing ISnapMode

        /// <summary>
        ///     Get the current snap mode.
        /// </summary>
        /// <returns>Current snap mode bitcode value.</returns>
        public int GetSnapMode()
        {
            return int.Parse(Application.GetSystemVariable("osmode").ToString());
        }

        /// <summary>
        ///     Set the snap mode.
        /// </summary>
        /// <param name="snapMode">Snap mode bitcode value.</param>
        public void SetSnapMode(int snapMode)
        {
            Application.SetSystemVariable("osmode", snapMode);
        }

        /// <summary>
        ///     Will calculate the sum of all object snap bitcode values within the collection.
        /// </summary>
        /// <param name="snapTypes">Collection of snaps</param>
        /// <returns>The sum of the snap bitcode values.</returns>
        public int CalculateSnapMode(IEnumerable<Snaps> snapTypes)
        {
            return snapTypes.Aggregate(0, (current, snapType) => current + Convert.ToInt16(snapType));
        }

        public void SetInitialSnapMode()
        {
            SetSnapMode(_initialSnapMode);
        }
        #endregion

    }
  • Example using the previous posts example
[CommandMethod("SnapablePolylineJig")]
        public void SnapablePolylineJig()
        {
            Polyline polyline;

            var mode = new SnapMode(new List<Snaps> { Snaps.Endpoint, Snaps.Center });

            try
            {
                var service = new PolylineJigService();

                polyline = service.Draw(true, true);
            }
            finally
            {
                mode.SetInitialSnapMode();
            }

            if (polyline != null)
            {
                // Use a for loop to get each vertex, one by one
                var vn = polyline.NumberOfVertices;

                var list = new List<Point2d>();

                for (var i = 0; i < vn; i++)
                {
                    // Could also get the 3D point here
                    var pt = polyline.GetPoint2dAt(i);
                    list.Add(new Point2d(pt.X, pt.Y));
                }
            }


            Document doc =
                Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // Now let's add the polyline to the modelspace
                Transaction tr =
                    db.TransactionManager.StartTransaction();
                using (tr)
                {
                    BlockTable bt =
                        (BlockTable) tr.GetObject(
                            db.BlockTableId,
                            OpenMode.ForRead
                                         );
                    BlockTableRecord btr =
                        (BlockTableRecord) tr.GetObject(
                            bt[BlockTableRecord.ModelSpace],
                            OpenMode.ForWrite
                                               );
                    ObjectId plineId = btr.AppendEntity(polyline);
                    tr.AddNewlyCreatedDBObject(polyline, true);
                    tr.Commit();
                    ed.WriteMessage("\nPolyline entity is: " +
                                    plineId.ToString()
                        );
                }
           
            // Clear the temp graphics (polyline should be in
            // the same location, if selection was not cancelled)
            // We could "redraw" instead of "regen" here
            ed.Regen();

        }