internal static ZumoTest CreatePopulateStringIdTableTest() { return(new ZumoTest("Populate [string id] movies table, if necessary", new TestExecution(async delegate(ZumoTest test) { var client = ZumoTestGlobals.Instance.Client; var table = client.GetTable <AllStringIdMovies>(); AllStringIdMovies allMovies = new AllStringIdMovies { Movies = new StringIdMovie[ZumoQueryTestData.AllStringIdMovies().Length] }; for (int i = 0; i < allMovies.Movies.Length; i++) { allMovies.Movies[i] = new StringIdMovie(string.Format("Movie {0:000}", i), ZumoQueryTestData.AllMovies[i]); } await table.InsertAsync(allMovies); for (int i = 0; i < 20; i++) { var counter = await table.Take(0).IncludeTotalCount().ToListAsync(); var totalCount = ((ITotalCountProvider)counter).TotalCount; if (totalCount == allMovies.Movies.Length) { test.AddLog("Result of populating [string id] table: {0}", allMovies.Status); return true; } else { test.AddLog("Already inserted {0} items, waiting for insertion to complete", totalCount); await Util.TaskDelay(5000); } } test.AddLog("Result of populating [string id] table: Time out. Not populate enough data."); return false; }), ZumoTestGlobals.RuntimeFeatureNames.STRING_ID_TABLES)); }
private static ZumoTest CreateTypedApiTest(Random seedGenerator, TypedTestType testType) { string testName = "Typed overload - " + testType; return(new ZumoTest(testName, async delegate(ZumoTest test) { var client = ZumoTestGlobals.Instance.Client; var apiName = MovieFinderApiName; var testResult = true; for (int i = 0; i < 10; i++) { int seed = seedGenerator.Next(); test.AddLog("Test with seed = {0}", seed); Random rndGen = new Random(seed); StringIdMovie[] expectedResult = null; AllStringIdMovies actualResult = null; StringIdMovie inputTemplate = ZumoQueryTestData.AllStringIdMovies()[rndGen.Next(ZumoQueryTestData.AllStringIdMovies().Length)]; test.AddLog("Using movie '{0}' as template", inputTemplate.Title); string apiUrl; switch (testType) { case TypedTestType.GetByTitle: apiUrl = apiName + "/title/" + inputTemplate.Title; expectedResult = new StringIdMovie[] { inputTemplate }; actualResult = await client.InvokeApiAsync <AllStringIdMovies>(apiUrl, HttpMethod.Get, null); break; case TypedTestType.GetByDate: var releaseDate = inputTemplate.ReleaseDate; apiUrl = apiName + "/date/" + releaseDate.Year + "/" + releaseDate.Month + "/" + releaseDate.Day; expectedResult = ZumoQueryTestData.AllStringIdMovies().Where(m => m.ReleaseDate == releaseDate).ToArray(); actualResult = await client.InvokeApiAsync <AllStringIdMovies>(apiUrl, HttpMethod.Get, null); break; case TypedTestType.PostByDuration: case TypedTestType.PostByYear: string orderBy = null; switch (rndGen.Next(3)) { case 0: orderBy = null; break; case 1: orderBy = "id"; break; case 2: orderBy = "Title"; break; } Dictionary <string, string> queryParams = orderBy == null ? null : new Dictionary <string, string> { { "orderBy", orderBy } }; Func <StringIdMovie, bool> predicate; if (testType == TypedTestType.PostByYear) { predicate = m => m.Year == inputTemplate.Year; apiUrl = apiName + "/moviesOnSameYear"; } else { predicate = m => m.Duration == inputTemplate.Duration; apiUrl = apiName + "/moviesWithSameDuration"; } if (queryParams == null) { actualResult = await client.InvokeApiAsync <StringIdMovie, AllStringIdMovies>(apiUrl, inputTemplate); } else { actualResult = await client.InvokeApiAsync <StringIdMovie, AllStringIdMovies>(apiUrl, inputTemplate, HttpMethod.Post, queryParams); } expectedResult = ZumoQueryTestData.AllStringIdMovies().Where(predicate).ToArray(); if (orderBy == null || orderBy == "Title") { Array.Sort(expectedResult, (m1, m2) => m1.Title.CompareTo(m2.Title)); } break; default: throw new ArgumentException("Invalid test type: " + testType); } test.AddLog(" - Sent request to {0}", apiUrl); List <string> errors = new List <string>(); if (Util.CompareArrays(expectedResult, actualResult.Movies, errors)) { test.AddLog(" - Result is expected"); } else { foreach (var error in errors) { test.AddLog(" - {0}", error); } test.AddLog("Expected: {0}", string.Join(", ", expectedResult.Select(m => m.Title))); test.AddLog("Actual: {0}", string.Join(", ", actualResult.Movies.Select(m => m.Title))); testResult = false; break; } } return testResult; }, ZumoTestGlobals.RuntimeFeatureNames.STRING_ID_TABLES)); }
private static ZumoTest CreateQueryTest <MovieType, TExpectedException>( string name, Expression <Func <MovieType, bool> > whereClause, int?top = null, int?skip = null, OrderByClause[] orderBy = null, Expression <Func <MovieType, string> > selectExpression = null, bool?includeTotalCount = null, string odataExpression = null, bool useStringIdTable = false) where MovieType : class, IMovie where TExpectedException : Exception { return(new ZumoTest(name, async delegate(ZumoTest test) { try { var table = ZumoTestGlobals.Instance.Client.GetTable <MovieType>(); IEnumerable <MovieType> readMovies = null; IEnumerable <string> readProjectedMovies = null; if (odataExpression == null) { IMobileServiceTableQuery <MovieType> query = null; IMobileServiceTableQuery <string> selectedQuery = null; if (whereClause != null) { query = table.Where(whereClause); } if (orderBy != null) { if (query == null) { query = table.Where(m => m.Duration == m.Duration); } query = ApplyOrdering(query, orderBy); } if (top.HasValue) { query = query == null ? table.Take(top.Value) : query.Take(top.Value); } if (skip.HasValue) { query = query == null ? table.Skip(skip.Value) : query.Skip(skip.Value); } if (selectExpression != null) { selectedQuery = query == null ? table.Select(selectExpression) : query.Select(selectExpression); } if (includeTotalCount.HasValue) { query = query.IncludeTotalCount(); } if (selectedQuery == null) { // Both ways of querying should be equivalent, so using both with equal probability here. var tickCount = Environment.TickCount; if ((tickCount % 2) == 0) { test.AddLog("Querying using MobileServiceTableQuery<T>.ToEnumerableAsync"); readMovies = await query.ToEnumerableAsync(); } else { test.AddLog("Querying using IMobileServiceTable<T>.ReadAsync(MobileServiceTableQuery<U>)"); readMovies = await table.ReadAsync(query); } } else { readProjectedMovies = await selectedQuery.ToEnumerableAsync(); } } else { test.AddLog("Using the OData query directly"); JToken result = await table.ReadAsync(odataExpression); if (ZumoTestGlobals.Instance.IsNetRuntime) { var serializer = new JsonSerializer(); serializer.Converters.Add(new MobileServiceIsoDateTimeConverter()); readMovies = result.ToObject <IEnumerable <MovieType> >(serializer); } else { readMovies = result.ToObject <IEnumerable <MovieType> >(); } } long actualTotalCount = -1; ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider); if (totalCountProvider != null) { actualTotalCount = totalCountProvider.TotalCount; } if (ZumoTestGlobals.Instance.IsNetRuntime && top.HasValue && top.Value == VeryLargeTopValue) { test.AddLog("NetRuntime throttles to 100 and does not throw"); return readMovies.Count() == 100; } IEnumerable <MovieType> expectedData; if (useStringIdTable) { var movies = ZumoQueryTestData.AllStringIdMovies(); expectedData = new MovieType[movies.Length]; for (var i = 0; i < movies.Length; i++) { ((MovieType[])expectedData)[i] = (MovieType)(IMovie)movies[i]; } } else { expectedData = ZumoQueryTestData.AllMovies.Select(s => (MovieType)(IMovie)s); } if (whereClause != null) { expectedData = expectedData.Where(whereClause.Compile()); } long expectedTotalCount = -1; if (includeTotalCount.HasValue && includeTotalCount.Value) { expectedTotalCount = expectedData.Count(); } if (orderBy != null) { expectedData = ApplyOrdering(expectedData, orderBy); } if (skip.HasValue) { expectedData = expectedData.Skip(skip.Value); } if (top.HasValue) { expectedData = expectedData.Take(top.Value); } if (includeTotalCount.HasValue) { if (expectedTotalCount != actualTotalCount) { test.AddLog("Total count was requested, but the returned value is incorrect: expected={0}, actual={1}", expectedTotalCount, actualTotalCount); return false; } } List <string> errors = new List <string>(); bool expectedDataIsSameAsReadData; if (selectExpression != null) { string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray(); expectedDataIsSameAsReadData = Util.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors); } else { expectedDataIsSameAsReadData = Util.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors); } if (!expectedDataIsSameAsReadData) { foreach (var error in errors) { test.AddLog(error); } test.AddLog("Expected data is different"); return false; } else { if (typeof(TExpectedException) == typeof(ExceptionTypeWhichWillNeverBeThrown)) { return true; } else { test.AddLog("Error, test should have failed with {0}, but succeeded.", typeof(TExpectedException).FullName); return false; } } } catch (TExpectedException ex) { test.AddLog("Caught expected exception - {0}: {1}", ex.GetType().FullName, ex.Message); return true; } }, typeof(MovieType) == typeof(Movie) ? ZumoTestGlobals.RuntimeFeatureNames.INT_ID_TABLES : ZumoTestGlobals.RuntimeFeatureNames.STRING_ID_TABLES)); }
internal static ZumoTestGroup CreateTests() { ZumoTestGroup result = new ZumoTestGroup("Query tests"); result.AddTest(CreatePopulateTableTest()); result.AddTest(CreatePopulateStringIdTableTest()); // Numeric fields result.AddTest(CreateQueryTestIntId("GreaterThan and LessThan - Movies from the 90s", m => m.Year > 1989 && m.Year < 2000)); result.AddTest(CreateQueryTestIntId("GreaterEqual and LessEqual - Movies from the 90s", m => m.Year >= 1990 && m.Year <= 1999)); result.AddTest(CreateQueryTestIntId("Compound statement - OR of ANDs - Movies from the 30s and 50s", m => ((m.Year >= 1930) && (m.Year < 1940)) || ((m.Year >= 1950) && (m.Year < 1960)))); result.AddTest(CreateQueryTestIntId("Division, equal and different - Movies from the year 2000 with rating other than R", m => ((m.Year / 1000.0) == 2) && (m.MPAARating != "R"))); result.AddTest(CreateQueryTestIntId("Addition, subtraction, relational, AND - Movies from the 1980s which last less than 2 hours", m => ((m.Year - 1900) >= 80) && (m.Year + 10 < 2000) && (m.Duration < 120))); result.AddTest(CreateQueryTestStringId("GreaterThan and LessThan - Movies from the 90s", m => m.Year > 1989 && m.Year < 2000)); result.AddTest(CreateQueryTestStringId("GreaterEqual and LessEqual - Movies from the 90s", m => m.Year >= 1990 && m.Year <= 1999)); result.AddTest(CreateQueryTestStringId("Compound statement - OR of ANDs - Movies from the 30s and 50s", m => ((m.Year >= 1930) && (m.Year < 1940)) || ((m.Year >= 1950) && (m.Year < 1960)))); result.AddTest(CreateQueryTestStringId("Division, equal and different - Movies from the year 2000 with rating other than R", m => ((m.Year / 1000.0) == 2) && (m.MPAARating != "R"))); result.AddTest(CreateQueryTestStringId("Addition, subtraction, relational, AND - Movies from the 1980s which last less than 2 hours", m => ((m.Year - 1900) >= 80) && (m.Year + 10 < 2000) && (m.Duration < 120))); // String functions result.AddTest(CreateQueryTestIntId("String: StartsWith - Movies which starts with 'The'", m => m.Title.StartsWith("The"), 100)); result.AddTest(CreateQueryTestIntId("String: StartsWith, case insensitive - Movies which start with 'the'", m => m.Title.ToLower().StartsWith("the"), 100)); result.AddTest(CreateQueryTestIntId("String: EndsWith, case insensitive - Movies which end with 'r'", m => m.Title.ToLower().EndsWith("r"))); result.AddTest(CreateQueryTestIntId("String: Contains - Movies which contain the word 'one', case insensitive", m => m.Title.ToUpper().Contains("ONE"))); result.AddTest(CreateQueryTestIntId("String: Length - Movies with small names", m => m.Title.Length < 10, 200)); result.AddTest(CreateQueryTestIntId("String: Substring (1 parameter), length - Movies which end with 'r'", m => m.Title.Substring(m.Title.Length - 1) == "r")); result.AddTest(CreateQueryTestIntId("String: Substring (2 parameters), length - Movies which end with 'r'", m => m.Title.Substring(m.Title.Length - 1, 1) == "r")); result.AddTest(CreateQueryTestIntId("String: Replace - Movies ending with either 'Part 2' or 'Part II'", m => m.Title.Replace("II", "2").EndsWith("Part 2"))); result.AddTest(CreateQueryTestIntId("String: Concat - Movies rated 'PG' or 'PG-13' from the 2000s", m => m.Year >= 2000 && string.Concat(m.MPAARating, "-13").StartsWith("PG-13"))); result.AddTest(CreateQueryTestStringId("String: StartsWith - Movies which starts with 'The'", m => m.Title.StartsWith("The"), 100)); result.AddTest(CreateQueryTestStringId("String: StartsWith, case insensitive - Movies which start with 'the'", m => m.Title.ToLower().StartsWith("the"), 100)); result.AddTest(CreateQueryTestStringId("String: EndsWith, case insensitive - Movies which end with 'r'", m => m.Title.ToLower().EndsWith("r"))); result.AddTest(CreateQueryTestStringId("String: Contains - Movies which contain the word 'one', case insensitive", m => m.Title.ToUpper().Contains("ONE"))); result.AddTest(CreateQueryTestStringId("String: Length - Movies with small names", m => m.Title.Length < 10, 200)); result.AddTest(CreateQueryTestStringId("String: Substring (1 parameter), length - Movies which end with 'r'", m => m.Title.Substring(m.Title.Length - 1) == "r")); result.AddTest(CreateQueryTestStringId("String: Substring (2 parameters), length - Movies which end with 'r'", m => m.Title.Substring(m.Title.Length - 1, 1) == "r")); // The OData library in .NET does not support replace? result.AddTest(CreateQueryTestStringId("String: Replace - Movies ending with either 'Part 2' or 'Part II'", m => m.Title.Replace("II", "2").EndsWith("Part 2"))); result.AddTest(CreateQueryTestStringId("String: Concat - Movies rated 'PG' or 'PG-13' from the 2000s", m => m.Year >= 2000 && string.Concat(m.MPAARating, "-13").StartsWith("PG-13"))); // String fields result.AddTest(CreateQueryTestIntId("String equals - Movies since 1980 with rating PG-13", m => m.Year >= 1980 && m.MPAARating == "PG-13", 100)); result.AddTest(CreateQueryTestIntId("String field, comparison to null - Movies since 1980 without a MPAA rating", m => m.Year >= 1980 && m.MPAARating == null)); result.AddTest(CreateQueryTestIntId("String field, comparison (not equal) to null - Movies before 1970 with a MPAA rating", m => m.Year < 1970 && m.MPAARating != null)); result.AddTest(CreateQueryTestStringId("String equals - Movies since 1980 with rating PG-13", m => m.Year >= 1980 && m.MPAARating == "PG-13", 100)); result.AddTest(CreateQueryTestStringId("String field, comparison to null - Movies since 1980 without a MPAA rating", m => m.Year >= 1980 && m.MPAARating == null)); result.AddTest(CreateQueryTestStringId("String field, comparison (not equal) to null - Movies before 1970 with a MPAA rating", m => m.Year < 1970 && m.MPAARating != null)); // Numeric functions result.AddTest(CreateQueryTestIntId("Floor - Movies which last more than 3 hours", m => Math.Floor(m.Duration / 60.0) >= 3)); result.AddTest(CreateQueryTestIntId("Ceiling - Best picture winners which last at most 2 hours", m => m.BestPictureWinner == true && Math.Ceiling(m.Duration / 60.0) == 2)); result.AddTest(CreateQueryTestIntId("Round - Best picture winners which last more than 2.5 hours", m => m.BestPictureWinner == true && Math.Round(m.Duration / 60.0) > 2)); result.AddTest(CreateQueryTestStringId("Floor - Movies which last more than 3 hours", m => Math.Floor(m.Duration / 60.0) >= 3)); result.AddTest(CreateQueryTestStringId("Ceiling - Best picture winners which last at most 2 hours", m => m.BestPictureWinner == true && Math.Ceiling(m.Duration / 60.0) == 2)); result.AddTest(CreateQueryTestStringId("Round - Best picture winners which last more than 2.5 hours", m => m.BestPictureWinner == true && Math.Round(m.Duration / 60.0) > 2)); // Date fields result.AddTest(CreateQueryTestIntId("Date: Greater than, less than - Movies with release date in the 70s", m => m.ReleaseDate > new DateTime(1969, 12, 31, 0, 0, 0, DateTimeKind.Utc) && m.ReleaseDate < new DateTime(1971, 1, 1, 0, 0, 0, DateTimeKind.Utc))); result.AddTest(CreateQueryTestIntId("Date: Greater than, less than - Movies with release date in the 80s", m => m.ReleaseDate >= new DateTime(1980, 1, 1, 0, 0, 0, DateTimeKind.Utc) && m.ReleaseDate < new DateTime(1989, 12, 31, 23, 59, 59, DateTimeKind.Utc))); result.AddTest(CreateQueryTestIntId("Date: Equal - Movies released on 1994-10-14 (Shawshank Redemption / Pulp Fiction)", m => m.ReleaseDate == new DateTime(1994, 10, 14, 0, 0, 0, DateTimeKind.Utc))); result.AddTest(CreateQueryTestStringId("Date: Greater than, less than - Movies with release date in the 70s", m => m.ReleaseDate > new DateTime(1969, 12, 31, 0, 0, 0, DateTimeKind.Utc) && m.ReleaseDate < new DateTime(1971, 1, 1, 0, 0, 0, DateTimeKind.Utc))); result.AddTest(CreateQueryTestStringId("Date: Greater than, less than - Movies with release date in the 80s", m => m.ReleaseDate >= new DateTime(1980, 1, 1, 0, 0, 0, DateTimeKind.Utc) && m.ReleaseDate < new DateTime(1989, 12, 31, 23, 59, 59, DateTimeKind.Utc))); result.AddTest(CreateQueryTestStringId("Date: Equal - Movies released on 1994-10-14 (Shawshank Redemption / Pulp Fiction)", m => m.ReleaseDate == new DateTime(1994, 10, 14, 0, 0, 0, DateTimeKind.Utc))); // Date functions result.AddTest(CreateQueryTestIntId("Date (month): Movies released in November", m => m.ReleaseDate.Month == 11)); result.AddTest(CreateQueryTestIntId("Date (day): Movies released in the first day of the month", m => m.ReleaseDate.Day == 1)); result.AddTest(CreateQueryTestIntId("Date (year): Movies whose year is different than its release year", m => m.ReleaseDate.Year != m.Year, 100)); result.AddTest(CreateQueryTestStringId("Date (month): Movies released in November", m => m.ReleaseDate.Month == 11)); result.AddTest(CreateQueryTestStringId("Date (day): Movies released in the first day of the month", m => m.ReleaseDate.Day == 1)); result.AddTest(CreateQueryTestStringId("Date (year): Movies whose year is different than its release year", m => m.ReleaseDate.Year != m.Year, 100)); // Bool fields result.AddTest(CreateQueryTestIntId("Bool: equal to true - Best picture winners before 1950", m => m.Year < 1950 && m.BestPictureWinner == true)); result.AddTest(CreateQueryTestIntId("Bool: equal to false - Best picture winners after 2000", m => m.Year >= 2000 && !(m.BestPictureWinner == false))); result.AddTest(CreateQueryTestIntId("Bool: not equal to false - Best picture winners after 2000", m => m.BestPictureWinner != false && m.Year >= 2000)); result.AddTest(CreateQueryTestStringId("Bool: equal to true - Best picture winners before 1950", m => m.Year < 1950 && m.BestPictureWinner == true)); result.AddTest(CreateQueryTestStringId("Bool: equal to false - Best picture winners after 2000", m => m.Year >= 2000 && !(m.BestPictureWinner == false))); result.AddTest(CreateQueryTestStringId("Bool: not equal to false - Best picture winners after 2000", m => m.BestPictureWinner != false && m.Year >= 2000)); // Top and skip result.AddTest(CreateQueryTestIntId("Get all using large $top - 500", null, 500)); result.AddTest(CreateQueryTestIntId("Skip all using large skip - 500", null, null, 500)); result.AddTest(CreateQueryTestIntId("Get first ($top) - 10", null, 10)); result.AddTest(CreateQueryTestIntId("Get last ($skip) - 10", null, null, ZumoQueryTestData.AllMovies.Length - 10)); result.AddTest(CreateQueryTestIntId("Skip, take, includeTotalCount - movies 11-20, ordered by title", null, 10, 10, new[] { new OrderByClause("Title", true) }, null, true)); result.AddTest(CreateQueryTestIntId("Skip, take, filter includeTotalCount - movies 11-20 which won a best picture award, ordered by year", m => m.BestPictureWinner == true, 10, 10, new[] { new OrderByClause("Year", false) }, null, true)); result.AddTest(CreateQueryTestStringId("Get all using large $top - 500", null, 500)); result.AddTest(CreateQueryTestStringId("Skip all using large skip - 500", null, null, 500)); result.AddTest(CreateQueryTestStringId("Get first ($top) - 10", null, 10)); result.AddTest(CreateQueryTestStringId("Get last ($skip) - 10", null, null, ZumoQueryTestData.AllStringIdMovies().Length - 10)); result.AddTest(CreateQueryTestStringId("Skip, take, includeTotalCount - movies 11-20, ordered by title", null, 10, 10, new[] { new OrderByClause("Title", true) }, null, true)); result.AddTest(CreateQueryTestStringId("Skip, take, filter includeTotalCount - movies 11-20 which won a best picture award, ordered by year", m => m.BestPictureWinner == true, 10, 10, new[] { new OrderByClause("Year", false) }, null, true)); // Order by result.AddTest(CreateQueryTestIntId("Order by date and string - 50 movies, ordered by release date, then title", null, 50, null, new[] { new OrderByClause("ReleaseDate", false), new OrderByClause("Title", true) })); result.AddTest(CreateQueryTestIntId("Order by number - 30 shortest movies since 1970", m => m.Year >= 1970, 30, null, new[] { new OrderByClause("Duration", true), new OrderByClause("Title", true) }, null, true)); result.AddTest(CreateQueryTestStringId("Order by date and string - 50 movies, ordered by release date, then title", null, 50, null, new[] { new OrderByClause("ReleaseDate", false), new OrderByClause("Title", true) })); result.AddTest(CreateQueryTestStringId("Order by number - 30 shortest movies since 1970", m => m.Year >= 1970, 30, null, new[] { new OrderByClause("Duration", true), new OrderByClause("Title", true) }, null, true)); // Select result.AddTest(CreateQueryTestIntId("Select one field - Only title of movies from 2008", m => m.Year == 2008, null, null, null, m => m.Title)); result.AddTest(CreateQueryTestIntId("Select multiple fields - Nicely formatted list of movies from the 2000's", m => m.Year >= 2000, 200, null, new[] { new OrderByClause("ReleaseDate", false), new OrderByClause("Title", true) }, m => string.Format("{0} {1} - {2} minutes", m.Title.PadRight(30), m.BestPictureWinner ? "(best picture)" : "", m.Duration))); result.AddTest(CreateQueryTestStringId("Select one field - Only title of movies from 2008", m => m.Year == 2008, null, null, null, m => m.Title)); result.AddTest(CreateQueryTestStringId("Select multiple fields - Nicely formatted list of movies from the 2000's", m => m.Year >= 2000, 200, null, new[] { new OrderByClause("ReleaseDate", false), new OrderByClause("Title", true) }, m => string.Format("{0} {1} - {2} minutes", m.Title.PadRight(30), m.BestPictureWinner ? "(best picture)" : "", m.Duration))); // Tests passing the OData query directly to the Read operation result.AddTest(CreateQueryTestIntId("Passing OData query directly - movies from the 80's, ordered by Title, items 3, 4 and 5", whereClause: m => m.Year >= 1980 && m.Year <= 1989, top: 3, skip: 2, orderBy: new OrderByClause[] { new OrderByClause("Title", true) }, odataQueryExpression: "$filter=((Year ge 1980) and (Year le 1989))&$top=3&$skip=2&$orderby=Title asc")); result.AddTest(CreateQueryTestStringId("Passing OData query directly - movies from the 80's, ordered by Title, items 3, 4 and 5", whereClause: m => m.Year >= 1980 && m.Year <= 1989, top: 3, skip: 2, orderBy: new OrderByClause[] { new OrderByClause("Title", true) }, odataQueryExpression: "$filter=((Year ge 1980) and (Year le 1989))&$top=3&$skip=2&$orderby=Title asc")); // Negative tests result.AddTest(CreateQueryTest <Movie, MobileServiceInvalidOperationException>("[Int id] (Neg) Very large top value", m => m.Year > 2000, VeryLargeTopValue)); result.AddTest(CreateQueryTest <StringIdMovie, MobileServiceInvalidOperationException>("[String id] (Neg) Very large top value", m => m.Year > 2000, VeryLargeTopValue)); result.AddTest(CreateQueryTest <Movie, NotSupportedException>("[Int id] (Neg) Unsupported predicate: unsupported arithmetic", m => Math.Sqrt(m.Year) > 43)); result.AddTest(CreateQueryTest <StringIdMovie, NotSupportedException>("[String id] (Neg) Unsupported predicate: unsupported arithmetic", m => Math.Sqrt(m.Year) > 43)); // Invalid lookup for (int i = -1; i <= 0; i++) { int id = i; result.AddTest(new ZumoTest("(Neg) Invalid id for lookup: " + i, async delegate(ZumoTest test) { var table = ZumoTestGlobals.Instance.Client.GetTable <Movie>(); try { var item = await table.LookupAsync(id); test.AddLog("Error, LookupAsync for id = {0} should have failed, but succeeded: {1}", id, item); return(false); } catch (InvalidOperationException ex) { test.AddLog("Caught expected exception - {0}: {1}", ex.GetType().FullName, ex.Message); return(true); } }, ZumoTestGlobals.RuntimeFeatureNames.INT_ID_TABLES)); } #if !WINDOWS_PHONE result.AddTest(new ZumoTest("ToCollection - displaying movies on a ListBox", async delegate(ZumoTest test) { var client = ZumoTestGlobals.Instance.Client; var table = client.GetTable <StringIdMovie>(); var query = from m in table where m.Year > 1980 orderby m.ReleaseDate descending select new { Date = m.ReleaseDate.ToUniversalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), Title = m.Title }; query = query.Take(50); var expectedItems = ZumoQueryTestData.AllMovies .Where(m => m.Year > 1980) .OrderByDescending(m => m.ReleaseDate) .Select(m => string.Format( "{0} - {1}", m.ReleaseDate.ToUniversalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), m.Title)) .Take(50) .ToList(); var newPage = new MoviesDisplayControl(); var collection = await query.ToCollectionAsync(); newPage.SetMoviesSource(collection); test.AddLog("Displaying the movie display control with the bound collection"); await newPage.Display(); test.AddLog("Dialog displayed, verifying that the items displayed are correct..."); var pageItems = newPage.ItemsAsString; List <string> errors = new List <string>(); if (Util.CompareArrays(expectedItems.ToArray(), pageItems.ToArray(), errors)) { test.AddLog("Movies were displayed correctly."); return(true); } else { test.AddLog("Error comparing the movies:"); foreach (var error in errors) { test.AddLog(" {0}", error); } return(false); } }, ZumoTestGlobals.RuntimeFeatureNames.STRING_ID_TABLES)); #endif return(result); }