public static void Test(T value, IDbConnection connection, string sqlType)
            {
                using (IDbTransaction t = connection.BeginTransaction())
                {
                    // special case for formatting enums in our proc definition
                    string stringValue = value.ToString();
                    if (typeof(T).IsEnum)
                    {
                        stringValue = Enum.Format(typeof(T), value, "D");
                    }

                    // generate the test proc name
                    string procName       = typeof(T).Name;
                    Type   underlyingType = Nullable.GetUnderlyingType(typeof(T));
                    if (underlyingType != null)
                    {
                        procName = "Nullable_" + underlyingType.Name;
                    }
                    procName += sqlType.Split(new char[] { '(' }, 2)[0];

                    connection.ExecuteSql(String.Format(
                                              "CREATE PROCEDURE Insight_TestOutput_{2} @p {0} = NULL OUTPUT AS SET @p = CONVERT({0}, '{1}')",
                                              sqlType,
                                              stringValue,
                                              procName),
                                          transaction: t);

                    var command = connection.CreateCommand("Insight_TestOutput_" + procName, transaction: t);
                    var result  = command.ExecuteNonQuery();

                    var outputData = new ReturnTypeTest <T>();
                    command.OutputParameters(outputData);

                    Assert.AreEqual(value.ToString(), outputData.p.ToString());
                }
            }
        public void TestTypes()
        {
            using (var _connection = Connection().OpenConnection())
            {
                // value types
                // NOTE: unsigned types are not supported by sql so we won't test them here
                ReturnTypeTest <string> .Test("string", _connection, "varchar(32)");

                ReturnTypeTest <string> .Test("string", _connection, "nvarchar(32)");

                ReturnTypeTest <string> .Test("string", _connection, "char(6)");

                ReturnTypeTest <string> .Test("string", _connection, "nchar(6)");

                ReturnTypeTest <byte> .Test(1, _connection, "tinyint");

                ReturnTypeTest <short> .Test(-2, _connection, "smallint");

                ReturnTypeTest <int> .Test(-120, _connection, "int");

                ReturnTypeTest <long> .Test(-120000000, _connection, "bigint");

                ReturnTypeTest <float> .Test(123.456f, _connection, "float");

                ReturnTypeTest <double> .Test(567, _connection, "real");

                ReturnTypeTest <decimal> .Test(890.12345m, _connection, "decimal(18,5)");

                ReturnTypeTest <bool> .Test(false, _connection, "bit");

                ReturnTypeTest <bool> .Test(true, _connection, "bit");

                ReturnTypeTest <char> .Test('c', _connection, "char");

                ReturnTypeTest <Guid> .Test(Guid.NewGuid(), _connection, "uniqueidentifier");

                ReturnTypeTest <DateTime> .Test(DateTime.Now.Date, _connection, "date");                                        // SQL will round the time, so need to knock off some milliseconds

                ReturnTypeTest <DateTimeOffset> .Test(DateTimeOffset.Now, _connection, "datetimeoffset");

                ReturnTypeTest <TimeSpan> .Test(TimeSpan.Parse("00:01:15"), _connection, "time");

                ReturnTypeTest <TimeSpan> .Test(TimeSpan.Parse("00:01:15"), _connection, "datetime");

                ReturnTypeTest <Nullable <byte> > .Test(1, _connection, "tinyint");

                ReturnTypeTest <Nullable <short> > .Test(-2, _connection, "smallint");

                ReturnTypeTest <Nullable <int> > .Test(-120, _connection, "int");

                ReturnTypeTest <Nullable <long> > .Test(-120000000, _connection, "bigint");

                ReturnTypeTest <Nullable <float> > .Test(123.456f, _connection, "float");

                ReturnTypeTest <Nullable <double> > .Test(567, _connection, "real");

                ReturnTypeTest <Nullable <decimal> > .Test(890.12345m, _connection, "decimal(18,5)");

                ReturnTypeTest <Nullable <bool> > .Test(false, _connection, "bit");

                ReturnTypeTest <Nullable <bool> > .Test(true, _connection, "bit");

                ReturnTypeTest <Nullable <char> > .Test('c', _connection, "char");

                ReturnTypeTest <Nullable <Guid> > .Test(Guid.NewGuid(), _connection, "uniqueidentifier");

                ReturnTypeTest <Nullable <DateTime> > .Test(DateTime.Now.Date, _connection, "date");                                            // SQL will round the time, so need to knock off some milliseconds

                ReturnTypeTest <Nullable <DateTimeOffset> > .Test(DateTimeOffset.Now, _connection, "datetimeoffset");

                ReturnTypeTest <Nullable <TimeSpan> > .Test(TimeSpan.Parse("00:01:15"), _connection, "time");

                ReturnTypeTest <Nullable <TimeSpan> > .Test(TimeSpan.Parse("00:01:15"), _connection, "datetime");

                // enums
                ReturnTypeTest <TestEnum> .Test(TestEnum.Two, _connection, "int");
            }
        }