コード例 #1
0
        private static ZumoTest CreateSetupSchemaTest()
        {
            return(new ZumoTest("Setup dynamic schema", async delegate(ZumoTest test)
            {
                var client = ZumoTestGlobals.Instance.Client;
                Random rndGen = new Random(1);
                try
                {
                    if (!ZumoTestGlobals.Instance.IsNetRuntime)
                    {
                        var table = client.GetTable <RoundTripTableItem>();
                        RoundTripTableItem item = new RoundTripTableItem
                        {
                            Bool1 = true,
                            ComplexType1 = new ComplexType[] { new ComplexType(rndGen) },
                            ComplexType2 = new ComplexType2(rndGen),
                            Date1 = DateTime.Now,
                            Double1 = 123.456,
                            EnumType = EnumType.First,
                            Int1 = 1,
                            Long1 = 1,
                            String1 = "hello",
                        };

                        await table.InsertAsync(item);
                        test.AddLog("Inserted item to create schema on the int id table");
                    }

                    var table2 = client.GetTable <StringIdRoundTripTableItem>();
                    var item2 = new StringIdRoundTripTableItem {
                        Bool = true, Name = "hello", Number = 1.23, ComplexType = "a b c".Split(), Date = DateTime.UtcNow
                    };
                    await table2.InsertAsync(item2);
                    test.AddLog("Inserted item to create schema on the string id table");

                    return true;
                }
                catch (Exception ex)
                {
                    test.AddLog("Error setting up the dynamic schema: {0}", ex);
                    return false;
                }
            }, ZumoTestGlobals.RuntimeFeatureNames.INT_ID_TABLES, ZumoTestGlobals.RuntimeFeatureNames.STRING_ID_TABLES));
        }
コード例 #2
0
        public static ZumoTestGroup CreateTests()
        {
            ZumoTestGroup result = new ZumoTestGroup("Round trip tests");

            result.AddTest(CreateSetupSchemaTest());

            DateTime now    = DateTime.UtcNow;
            int      seed   = now.Year * 10000 + now.Month * 100 + now.Day;
            Random   rndGen = new Random(seed);

            result.AddTest(CreateSimpleTypedRoundTripTest("String: Empty", RoundTripTestType.String, ""));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: null", RoundTripTestType.String, null));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: random value",
                                                          RoundTripTestType.String, Util.CreateSimpleRandomString(rndGen, 10)));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: large (1000 characters)", RoundTripTestType.String, new string('*', 1000)));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: large (64k+1 characters)", RoundTripTestType.String, new string('*', 65537)));

            result.AddTest(CreateSimpleTypedRoundTripTest("String: non-ASCII characters - Latin", RoundTripTestType.String, "ãéìôü ÇñÑ"));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: non-ASCII characters - Arabic", RoundTripTestType.String, "الكتاب على الطاولة"));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: non-ASCII characters - Chinese", RoundTripTestType.String, "这本书在桌子上"));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: non-ASCII characters - Chinese 2", RoundTripTestType.String, "⒈①Ⅻㄨㄩ 啊阿鼾齄 丂丄狚狛 狜狝﨨﨩 ˊˋ˙–〇 㐀㐁䶴䶵"));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: non-ASCII characters - Japanese", RoundTripTestType.String, "本は机の上に"));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: non-ASCII characters - Hebrew", RoundTripTestType.String, "הספר הוא על השולחן"));
            result.AddTest(CreateSimpleTypedRoundTripTest("String: non-ASCII characters - Russian", RoundTripTestType.String, "Книга лежит на столе"));

            result.AddTest(CreateSimpleTypedRoundTripTest("Date: now", RoundTripTestType.Date, Util.TrimSubMilliseconds(DateTime.Now)));
            result.AddTest(CreateSimpleTypedRoundTripTest("Date: now (UTC)", RoundTripTestType.Date, Util.TrimSubMilliseconds(DateTime.UtcNow)));
            result.AddTest(CreateSimpleTypedRoundTripTest("Date: null", RoundTripTestType.Date, null));
            result.AddTest(CreateSimpleTypedRoundTripTest("Date: min date", RoundTripTestType.Date, DateTime.MinValue));
            result.AddTest(CreateSimpleTypedRoundTripTest("Date: specific date, before unix 0", RoundTripTestType.Date, new DateTime(1901, 1, 1)));
            result.AddTest(CreateSimpleTypedRoundTripTest("Date: specific date, after unix 0", RoundTripTestType.Date, new DateTime(2000, 12, 31)));

            result.AddTest(CreateSimpleTypedRoundTripTest("Bool: true", RoundTripTestType.Bool, true));
            result.AddTest(CreateSimpleTypedRoundTripTest("Bool: false", RoundTripTestType.Bool, false));
            result.AddTest(CreateSimpleTypedRoundTripTest("Bool: null", RoundTripTestType.Bool, null));

            result.AddTest(CreateSimpleTypedRoundTripTest("Int: zero", RoundTripTestType.Int, 0));
            result.AddTest(CreateSimpleTypedRoundTripTest("Int: MaxValue", RoundTripTestType.Int, int.MaxValue));
            result.AddTest(CreateSimpleTypedRoundTripTest("Int: MinValue", RoundTripTestType.Int, int.MinValue));

            result.AddTest(CreateSimpleTypedRoundTripTest("Long: zero", RoundTripTestType.Long, 0L));
            long maxAllowedValue = 0x0020000000000000;
            long minAllowedValue = 0;

            unchecked
            {
                minAllowedValue = (long)0xFFE0000000000000;
            }

            result.AddTest(CreateSimpleTypedRoundTripTest("Long: max allowed", RoundTripTestType.Long, maxAllowedValue));
            result.AddTest(CreateSimpleTypedRoundTripTest("Long: min allowed", RoundTripTestType.Long, minAllowedValue));
            long largePositiveValue = maxAllowedValue - rndGen.Next(0, int.MaxValue);
            long largeNegativeValue = minAllowedValue + rndGen.Next(0, int.MaxValue);

            result.AddTest(CreateSimpleTypedRoundTripTest("Long: large value, less than max allowed (" + largePositiveValue + ")", RoundTripTestType.Long, largePositiveValue));
            result.AddTest(CreateSimpleTypedRoundTripTest("Long: large negative value, more than min allowed (" + largeNegativeValue + ")", RoundTripTestType.Long, largeNegativeValue));

            result.AddTest(CreateSimpleTypedRoundTripTest <InvalidOperationException>("(Neg) Long: more than max allowed", RoundTripTestType.Long, maxAllowedValue + 1));
            result.AddTest(CreateSimpleTypedRoundTripTest <InvalidOperationException>("(Neg) Long: less than min allowed", RoundTripTestType.Long, minAllowedValue - 1));

            result.AddTest(CreateSimpleTypedRoundTripTest("Enum (with JSON converter): simple value", RoundTripTestType.Enum, EnumType.Second));

            result.AddTest(CreateSimpleTypedRoundTripTest(
                               "Complex type (custom table serialization): simple value",
                               RoundTripTestType.ComplexWithCustomSerialization,
                               new ComplexType2(rndGen)));
            result.AddTest(CreateSimpleTypedRoundTripTest(
                               "Complex type (custom table serialization): null",
                               RoundTripTestType.ComplexWithCustomSerialization,
                               null));

            result.AddTest(CreateSimpleTypedRoundTripTest(
                               "Complex type (converter): empty array",
                               RoundTripTestType.ComplexWithConverter,
                               new ComplexType[0]));
            result.AddTest(CreateSimpleTypedRoundTripTest(
                               "Complex type (converter): 1-element array",
                               RoundTripTestType.ComplexWithConverter,
                               new ComplexType[] { new ComplexType(rndGen) }));
            result.AddTest(CreateSimpleTypedRoundTripTest(
                               "Complex type (converter): multi-element array",
                               RoundTripTestType.ComplexWithConverter,
                               new ComplexType[] { new ComplexType(rndGen), null, new ComplexType(rndGen) }));
            result.AddTest(CreateSimpleTypedRoundTripTest(
                               "Complex type (converter): null array",
                               RoundTripTestType.ComplexWithConverter,
                               null));

            result.AddTest(
                CreateSimpleTypedRoundTripTest <ArgumentException>(
                    "(Neg) Insert item with non-default id", RoundTripTestType.Id, 1));

            var uniqueId     = Environment.TickCount.ToString(CultureInfo.InvariantCulture);
            var differentIds = new Dictionary <string, string>
            {
                { "none", null },
                { "ascii", "myid" },
                { "latin", "ãéìôü ÇñÑ" },
                { "arabic", "الكتاب على الطاولة" },
                { "chinese", "这本书在桌子上" },
                { "hebrew", "הספר הוא על השולחן" }
            };

            foreach (var name in differentIds.Keys)
            {
                var id = differentIds[name];
                result.AddTest(new ZumoTest("String id - " + name + " id on insert", async delegate(ZumoTest test) {
                    var item   = new StringIdRoundTripTableItem(rndGen);
                    var itemId = id;
                    if (itemId != null)
                    {
                        itemId = itemId + "-" + Guid.NewGuid().ToString();
                    }

                    item.Id    = itemId;
                    var client = ZumoTestGlobals.Instance.Client;
                    var table  = client.GetTable <StringIdRoundTripTableItem>();
                    await table.InsertAsync(item);
                    test.AddLog("Inserted item with id = {0}", item.Id);
                    if (id != null && itemId != item.Id)
                    {
                        test.AddLog("Error, id passed to insert is not the same ({0}) as the id returned by the server ({1})", id, item.Id);
                        return(false);
                    }

                    var retrieved = await table.LookupAsync(item.Id);
                    test.AddLog("Retrieved item: {0}", retrieved);
                    if (!item.Equals(retrieved))
                    {
                        test.AddLog("Error, round-tripped item is different");
                        return(false);
                    }

                    test.AddLog("Now trying to insert an item with an existing id (should fail)");
                    try
                    {
                        await table.InsertAsync(new StringIdRoundTripTableItem {
                            Id = retrieved.Id, Name = "should not work"
                        });
                        test.AddLog("Error, insertion succeeded but it should have failed");
                        return(false);
                    }
                    catch (MobileServiceInvalidOperationException e)
                    {
                        test.AddLog("Caught expected exception: {0}", e);
                    }

                    test.AddLog("Cleaning up...");
                    await table.DeleteAsync(retrieved);
                    test.AddLog("Removed the inserted item");
                    return(true);
                }));
            }

            var invalidIds = new string[] { ".", "..", "control\u0010characters", "large id " + new string('*', 260) };

            foreach (var id in invalidIds)
            {
                result.AddTest(new ZumoTest("(Neg) string id - insert with invalid id: " + (id.Length > 30 ? (id.Substring(0, 30) + "...") : id), async delegate(ZumoTest test)
                {
                    var client = ZumoTestGlobals.Instance.Client;
                    var table  = client.GetTable <StringIdRoundTripTableItem>();
                    var item   = new StringIdRoundTripTableItem {
                        Id = id, Name = "should not work"
                    };
                    try
                    {
                        await table.InsertAsync(item);
                        test.AddLog("Error, insert operation should have failed. Inserted id = {0}", item.Id);
                        return(false);
                    }
                    catch (InvalidOperationException ex)
                    {
                        test.AddLog("Caught expected exception: {0}", ex);
                        return(true);
                    }
                }));
            }

            // Untyped overloads
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: Empty", "string1", ""));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: null", "string1", null));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: random value",
                                                            "string1", Util.CreateSimpleRandomString(rndGen, 10)));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: large (1000 characters)", "string1", new string('*', 1000)));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: large (64k+1 characters)", "string1", new string('*', 65537)));

            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: non-ASCII characters - Latin", "string1", "ãéìôü ÇñÑ"));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: non-ASCII characters - Arabic", "string1", "الكتاب على الطاولة"));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: non-ASCII characters - Chinese", "string1", "这本书在桌子上"));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: non-ASCII characters - Chinese 2", "string1", "⒈①Ⅻㄨㄩ 啊阿鼾齄 丂丄狚狛 狜狝﨨﨩 ˊˋ˙–〇 㐀㐁䶴䶵"));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: non-ASCII characters - Japanese", "string1", "本は机の上に"));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: non-ASCII characters - Hebrew", "string1", "הספר הוא על השולחן"));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped String: non-ASCII characters - Russian", "string1", "Книга лежит на столе"));

            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Date: now", "date1", Util.TrimSubMilliseconds(DateTime.Now)));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Date: now (UTC)", "date1", Util.TrimSubMilliseconds(DateTime.UtcNow)));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Date: null", "date1", null));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Date: min date", "date1", DateTime.MinValue));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Date: specific date, before unix 0", "date1", new DateTime(1901, 1, 1)));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Date: specific date, after unix 0", "date1", new DateTime(2000, 12, 31)));

            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Bool: true", "bool1", true));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Bool: false", "bool1", false));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Bool: null", "bool1", null));

            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Int: zero", "int1", 0));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Int: MaxValue", "int1", int.MaxValue));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Int: MinValue", "int1", int.MinValue));

            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Long: zero", "long1", 0L));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Long: max allowed", "long1", maxAllowedValue));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Long: min allowed", "long1", minAllowedValue));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Long: more than max allowed (positive) for typed", "long1", maxAllowedValue + 1));
            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped Long: more than max allowed (negative) for typed", "long1", minAllowedValue - 1));

            result.AddTest(CreateSimpleUntypedRoundTripTest("Untyped complex (object): simple value",
                                                            JObject.Parse(@"{""complexType2"":{""Name"":""John Doe"",""Age"":33,""Friends"":[""Jane Roe"", ""John Smith""]}}")));
            result.AddTest(CreateSimpleUntypedRoundTripTest(
                               "Untyped complex (object): null",
                               JObject.Parse(@"{""complexType2"":null}")));

            result.AddTest(CreateSimpleUntypedRoundTripTest(
                               "Untyped complex (array): simple value",
                               JObject.Parse(@"{""complexType1"":[{""Name"":""Scooby"",""Age"":10}, {""Name"":""Shaggy"",""Age"":19}]}")));
            result.AddTest(CreateSimpleUntypedRoundTripTest(
                               "Untyped complex (array): empty array",
                               JObject.Parse(@"{""complexType1"":[]}")));
            result.AddTest(CreateSimpleUntypedRoundTripTest(
                               "Untyped complex (array): null",
                               JObject.Parse(@"{""complexType1"":null}")));
            result.AddTest(CreateSimpleUntypedRoundTripTest(
                               "Untyped complex (array): array with null elements",
                               JObject.Parse(@"{""complexType1"":[{""Name"":""Scooby"",""Age"":10}, null, {""Name"":""Shaggy"",""Age"":19}]}")));

            result.AddTest(CreateSimpleUntypedRoundTripTest <ArgumentException>("(Neg) Insert item with non-default 'id' property",
                                                                                JObject.Parse("{\"id\":1,\"value\":2}"), false));
            result.AddTest(CreateSimpleUntypedRoundTripTest <ArgumentException>("(Neg) Insert item with non-default 'ID' property",
                                                                                JObject.Parse("{\"ID\":1,\"value\":2}"), false));
            result.AddTest(CreateSimpleUntypedRoundTripTest <ArgumentException>("(Neg) Insert item with non-default 'Id' property",
                                                                                JObject.Parse("{\"Id\":1,\"value\":2}"), false));

            uniqueId = (Environment.TickCount + 1).ToString(CultureInfo.InvariantCulture);

            var obj        = new StringIdRoundTripTableItem(rndGen);
            var properties = new Dictionary <string, object>
            {
                { "name", obj.Name },
                { "date1", obj.Date },
                { "bool", obj.Bool },
                { "number", obj.Number },
                { "complex", obj.ComplexType },
            };

            foreach (var name in differentIds.Keys)
            {
                foreach (var property in properties.Keys)
                {
                    var testName = "String id (untyped) - " + name + " id on insert - " + property;
                    var item     = JObjectFromValue(property, properties[property]);
                    var id       = differentIds[name];
                    if (id != null)
                    {
                        item.Add("id", id + "-" + property + "-" + Guid.NewGuid().ToString());
                    }

                    result.AddTest(CreateSimpleUntypedRoundTripTest(testName, item, true));
                }
            }

            foreach (var id in invalidIds)
            {
                var     testName = "(Neg) [string id] Insert item with invalid 'id' property: " + (id.Length > 30 ? (id.Substring(0, 30) + "...") : id);
                JObject jo       = new JObject(new JProperty("id", id), new JProperty("name", "should not work"));
                result.AddTest(CreateSimpleUntypedRoundTripTest <InvalidOperationException>(testName, jo, true));
            }

            return(result);
        }