private async Task QueryTests_Common() { Log("This test is known to fail in Xamarin -- see https://bugzilla.xamarin.com/show_bug.cgi?id=22955"); // Numeric fields await CreateQueryTestIntId("GreaterThan and LessThan - Movies from the 90s", m => m.Year > 1989 && m.Year < 2000); await CreateQueryTestIntId("GreaterEqual and LessEqual - Movies from the 90s", m => m.Year >= 1990 && m.Year <= 1999); await 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))); await CreateQueryTestIntId("Division, equal and different - Movies from the year 2001 with rating other than R", m => ((m.Year / 1000.5) == 2) && (m.MpaaRating != "R")); await 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)); await CreateQueryTestStringId("GreaterThan and LessThan - Movies from the 90s", m => m.Year > 1989 && m.Year < 2000); await CreateQueryTestStringId("GreaterEqual and LessEqual - Movies from the 90s", m => m.Year >= 1990 && m.Year <= 1999); await 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))); await CreateQueryTestStringId("Division, equal and different - Movies from the year 2001 with rating other than R", m => ((m.Year / 1000.5) == 2) && (m.MpaaRating != "R")); await 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 await CreateQueryTestIntId("String: StartsWith - Movies which starts with 'The'", m => m.Title.StartsWith("The"), 100); await CreateQueryTestIntId("String: StartsWith, case insensitive - Movies which start with 'the'", m => m.Title.ToLower().StartsWith("the"), 100); await CreateQueryTestIntId("String: EndsWith, case insensitive - Movies which end with 'r'", m => m.Title.ToLower().EndsWith("r")); await CreateQueryTestIntId("String: Contains - Movies which contain the word 'one', case insensitive", m => m.Title.ToUpper().Contains("ONE")); await CreateQueryTestIntId("String: Length - Movies with small names", m => m.Title.Length < 10, 200); await CreateQueryTestIntId("String: Substring (1 parameter), length - Movies which end with 'r'", m => m.Title.Substring(m.Title.Length - 1) == "r"); await CreateQueryTestIntId("String: Substring (2 parameters), length - Movies which end with 'r'", m => m.Title.Substring(m.Title.Length - 1, 1) == "r"); await CreateQueryTestIntId("String: Concat - Movies rated 'PG' or 'PG-13' from the 2000s", m => m.Year >= 2000 && string.Concat(m.MpaaRating, "-13").StartsWith("PG-13")); await CreateQueryTestStringId("String: StartsWith - Movies which starts with 'The'", m => m.Title.StartsWith("The"), 100); await CreateQueryTestStringId("String: StartsWith, case insensitive - Movies which start with 'the'", m => m.Title.ToLower().StartsWith("the"), 100); await CreateQueryTestStringId("String: EndsWith, case insensitive - Movies which end with 'r'", m => m.Title.ToLower().EndsWith("r")); await CreateQueryTestStringId("String: Contains - Movies which contain the word 'one', case insensitive", m => m.Title.ToUpper().Contains("ONE")); await CreateQueryTestStringId("String: Length - Movies with small names", m => m.Title.Length < 10, 200); await CreateQueryTestStringId("String: Substring (1 parameter), length - Movies which end with 'r'", m => m.Title.Substring(m.Title.Length - 1) == "r"); await CreateQueryTestStringId("String: Substring (2 parameters), length - Movies which end with 'r'", m => m.Title.Substring(m.Title.Length - 1, 1) == "r"); await 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 await CreateQueryTestIntId("String equals - Movies since 1980 with rating PG-13", m => m.Year >= 1980 && m.MpaaRating == "PG-13", 100); await CreateQueryTestIntId("String field, comparison to null - Movies since 1980 without a MPAA rating", m => m.Year >= 1980 && m.MpaaRating == null, whereLambda : m => m.Year >= 1980 && m.MpaaRating == null); await CreateQueryTestIntId("String field, comparison (not equal) to null - Movies before 1970 with a MPAA rating", m => m.Year < 1970 && m.MpaaRating != null, whereLambda : m => m.Year < 1970 && m.MpaaRating != null); await CreateQueryTestStringId("String equals - Movies since 1980 with rating PG-13", m => m.Year >= 1980 && m.MpaaRating == "PG-13", 100); await CreateQueryTestStringId("String field, comparison to null - Movies since 1980 without a MPAA rating", m => m.Year >= 1980 && m.MpaaRating == null, whereLambda : m => m.Year >= 1980 && m.MpaaRating == null); await CreateQueryTestStringId("String field, comparison (not equal) to null - Movies before 1970 with a MPAA rating", m => m.Year < 1970 && m.MpaaRating != null, whereLambda : m => m.Year < 1970 && m.MpaaRating != null); // Numeric functions await CreateQueryTestIntId("Floor - Movies which last more than 3 hours", m => Math.Floor(m.Duration / 60.0) >= 3); await CreateQueryTestIntId("Ceiling - Best picture winners which last at most 2 hours", m => m.BestPictureWinner == true && Math.Ceiling(m.Duration / 60.0) == 2); await CreateQueryTestIntId("Round - Best picture winners which last more than 2.5 hours", m => m.BestPictureWinner == true && Math.Round(m.Duration / 60.0) > 2); await CreateQueryTestStringId("Floor - Movies which last more than 3 hours", m => Math.Floor(m.Duration / 60.0) >= 3); await CreateQueryTestStringId("Ceiling - Best picture winners which last at most 2 hours", m => m.BestPictureWinner == true && Math.Ceiling(m.Duration / 60.0) == 2); await 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 await 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)); await 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)); await 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)); await 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)); await 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)); await 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 await CreateQueryTestIntId("Date (month): Movies released in November", m => m.ReleaseDate.Month == 11); await CreateQueryTestIntId("Date (day): Movies released in the first day of the month", m => m.ReleaseDate.Day == 1); await CreateQueryTestIntId("Date (year): Movies whose year is different than its release year", m => m.ReleaseDate.Year != m.Year, 100); await CreateQueryTestStringId("Date (month): Movies released in November", m => m.ReleaseDate.Month == 11); await CreateQueryTestStringId("Date (day): Movies released in the first day of the month", m => m.ReleaseDate.Day == 1); await CreateQueryTestStringId("Date (year): Movies whose year is different than its release year", m => m.ReleaseDate.Year != m.Year, 100); // Bool fields await CreateQueryTestIntId("Bool: equal to true - Best picture winners before 1950", m => m.Year < 1950 && m.BestPictureWinner == true); await CreateQueryTestIntId("Bool: equal to false - Best picture winners after 2000", m => m.Year >= 2000 && !(m.BestPictureWinner == false)); await CreateQueryTestIntId("Bool: not equal to false - Best picture winners after 2000", m => m.BestPictureWinner != false && m.Year >= 2000); await CreateQueryTestStringId("Bool: equal to true - Best picture winners before 1950", m => m.Year < 1950 && m.BestPictureWinner == true); await CreateQueryTestStringId("Bool: equal to false - Best picture winners after 2000", m => m.Year >= 2000 && !(m.BestPictureWinner == false)); await CreateQueryTestStringId("Bool: not equal to false - Best picture winners after 2000", m => m.BestPictureWinner != false && m.Year >= 2000); // Top and skip await CreateQueryTestIntId("Get all using large $top - 500", null, 500); await CreateQueryTestIntId("Skip all using large skip - 500", null, null, 500, new[] { new OrderByClause("Title", true) }); await CreateQueryTestIntId("Get first ($top) - 10", null, 10); await CreateQueryTestIntId("Get last ($skip) - 10", null, null, QueryTestData.TestIntIdMovies.Length - 10, new[] { new OrderByClause("Title", true) }); await CreateQueryTestIntId("Skip, take, includeTotalCount - movies 11-20, ordered by title", null, 10, 10, new[] { new OrderByClause("Title", true) }, null, true); await 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); await CreateQueryTestStringId("Get all using large $top - 500", null, 500); await CreateQueryTestStringId("Skip all using large skip - 500", null, null, 500); await CreateQueryTestStringId("Get first ($top) - 10", null, 10); await CreateQueryTestStringId("Get last ($skip) - 10", null, null, QueryTestData.TestMovies().Length - 10); await CreateQueryTestStringId("Skip, take, includeTotalCount - movies 11-20, ordered by title", null, 10, 10, new[] { new OrderByClause("Title", true) }, null, true); await 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 await 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) }); await 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); await 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) }); await 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 await CreateQueryTestIntId("Select one field - Only title of movies from 2008", m => m.Year == 2008, null, null, null, m => m.Title); await 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)); await CreateQueryTestStringId("Select one field - Only title of movies from 2008", m => m.Year == 2008, null, null, null, m => m.Title); await 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 await 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"); await 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 await CreateQueryTest <IntIdMovie, MobileServiceInvalidOperationException>("[Int id] (Neg) Very large top value", m => m.Year > 2000, VeryLargeTopValue); await CreateQueryTest <Movie, MobileServiceInvalidOperationException>("[String id] (Neg) Very large top value", m => m.Year > 2000, VeryLargeTopValue); await CreateQueryTest <IntIdMovie, NotSupportedException>("[Int id] (Neg) Unsupported predicate: unsupported arithmetic", m => Math.Sqrt(m.Year) > 43); await CreateQueryTest <Movie, 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; //(Neg) Invalid id for lookup: " + i var table = this.GetClient().GetTable <IntIdMovie>(); try { var item = await table.LookupAsync(id); Log("Error, LookupAsync for id = {0} should have failed, but succeeded: {1}", id, item); Assert.Fail(""); } catch (InvalidOperationException ex) { Log("Caught expected exception - {0}: {1}", ex.GetType().FullName, ex.Message); } } // TODO: Add this test back? //#if !WINDOWS_PHONE // // ToCollection - displaying movies on a ListBox // { // var client = this.GetClient(); // 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 = QueryTestData.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); // Log("Displaying the movie display control with the bound collection"); // await newPage.Display(); // Log("Dialog displayed, verifying that the items displayed are correct..."); // var pageItems = newPage.ItemsAsString; // List<string> errors = new List<string>(); // if (Utilities.CompareArrays(expectedItems.ToArray(), pageItems.ToArray(), errors)) // { // Log("Movies were displayed correctly."); // return; // } // else // { // Log("Error comparing the movies:"); // foreach (var error in errors) // { // Log(" {0}", error); // } // Assert.Fail(""); // } // } //#endif }
private async Task 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, Func <MovieType, bool> whereLambda = null) where MovieType : class, IMovie where TExpectedException : Exception { Log("### Executing {0}.", name); if (whereClause == null && whereLambda != null) { Assert.Fail("The argument 'whereLambda' is optional and can only be specified if 'whereClause' is also specified."); } try { var table = this.GetClient().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. // TODO: Make it deterministic var tickCount = Environment.TickCount; if ((tickCount % 2) == 0) { Log("Querying using MobileServiceTableQuery<T>.ToEnumerableAsync"); readMovies = await query.ToEnumerableAsync(); } else { Log("Querying using IMobileServiceTable<T>.ReadAsync(MobileServiceTableQuery<U>)"); readMovies = await table.ReadAsync(query); } } else { readProjectedMovies = await selectedQuery.ToEnumerableAsync(); } } else { Log("Using the OData query directly"); JToken result = await table.ReadAsync(odataExpression); readMovies = result.ToObject <IEnumerable <MovieType> >(); } long actualTotalCount = -1; ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider); if (totalCountProvider != null) { actualTotalCount = totalCountProvider.TotalCount; } IEnumerable <MovieType> expectedData; if (useStringIdTable) { var movies = QueryTestData.TestMovies(); expectedData = new MovieType[movies.Length]; for (var i = 0; i < movies.Length; i++) { ((MovieType[])expectedData)[i] = (MovieType)(IMovie)movies[i]; } } else { expectedData = QueryTestData.TestIntIdMovies.Select(s => (MovieType)(IMovie)s); } // Due to a Xamarin.iOS bug, Expression.Compile() does not work for some expression trees, // in which case we allow the caller to provide a lambda directly and we use it instead of // compiling the expression tree. if (whereLambda != null) { expectedData = expectedData.Where(whereLambda); } else 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) { Log("Total count was requested, but the returned value is incorrect: expected={0}, actual={1}", expectedTotalCount, actualTotalCount); Assert.Fail(""); return; } } List <string> errors = new List <string>(); bool expectedDataIsSameAsReadData; if (selectExpression != null) { string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray(); expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors); } else { expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors); } if (!expectedDataIsSameAsReadData) { foreach (var error in errors) { Log(error); } Log("Expected data is different"); Assert.Fail(""); return; } else { if (typeof(TExpectedException) == typeof(ExceptionTypeWhichWillNeverBeThrown)) { return; } else { Log("Error, test should have failed with {0}, but succeeded.", typeof(TExpectedException).FullName); Assert.Fail(""); return; } } } catch (TExpectedException ex) { Log("Caught expected exception - {0}: {1}", ex.GetType().FullName, ex.Message); return; } }
private async Task 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, Func <MovieType, bool> whereLambda = null) where MovieType : class, IMovie where TExpectedException : Exception { Assert.False(whereClause == null && whereLambda != null); try { var table = this.GetClient().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. // TODO: Make it deterministic var tickCount = Environment.TickCount; if ((tickCount % 2) == 0) { readMovies = await query.ToEnumerableAsync(); } else { readMovies = await table.ReadAsync(query); } } else { readProjectedMovies = await selectedQuery.ToEnumerableAsync(); } } else { JToken result = await table.ReadAsync(odataExpression); readMovies = result.ToObject <IEnumerable <MovieType> >(); } long actualTotalCount = -1; #pragma warning disable CS0618 // Type or member is obsolete ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider); #pragma warning restore CS0618 // Type or member is obsolete if (totalCountProvider != null) { actualTotalCount = totalCountProvider.TotalCount; } IEnumerable <MovieType> expectedData; if (useStringIdTable) { var movies = QueryTestData.TestMovies(); expectedData = new MovieType[movies.Length]; for (var i = 0; i < movies.Length; i++) { ((MovieType[])expectedData)[i] = (MovieType)(IMovie)movies[i]; } } else { expectedData = QueryTestData.TestIntIdMovies.Select(s => (MovieType)(IMovie)s); } // Due to a Xamarin.iOS bug, Expression.Compile() does not work for some expression trees, // in which case we allow the caller to provide a lambda directly and we use it instead of // compiling the expression tree. if (whereLambda != null) { expectedData = expectedData.Where(whereLambda); } else 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) { Assert.Equal(expectedTotalCount, actualTotalCount); } List <string> errors = new List <string>(); bool expectedDataIsSameAsReadData; if (selectExpression != null) { string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray(); expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors); } else { expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors); } Assert.True(expectedDataIsSameAsReadData); if (typeof(TExpectedException) != typeof(ExceptionTypeWhichWillNeverBeThrown)) { Assert.True(false, "Test should have failed"); return; } } catch (TExpectedException) { return; } }
private async Task CreateTypedApiTest(Random seedGenerator, TypedTestType testType) { Log("### Typed overload - {0}", testType); var client = GetClient(); var apiName = MovieFinderApiName; for (int i = 0; i < 10; i++) { int seed = seedGenerator.Next(); Log("Test with seed = {0}", seed); Random rndGen = new Random(seed); Movie[] expectedResult = null; AllMovies actualResult = null; Movie inputTemplate; // TODO: BUG #2132434: .NET runtime should allow URI's that end with a dot while (true) { inputTemplate = QueryTestData.TestMovies()[rndGen.Next(QueryTestData.TestMovies().Length)]; if (testType == TypedTestType.GetByTitle && inputTemplate.Title.EndsWith(".")) { // The .NET backend barfs and returns 404 if the URI ends with a dot, so let's get another movie continue; } if (testType == TypedTestType.GetByTitle && inputTemplate.Title.EndsWith("?")) { // The .NET & Node backend do not return anything if the URI ends with a '?' so let's get another movie continue; } break; } Log("Using movie '{0}' as template", inputTemplate.Title); string apiUrl; switch (testType) { case TypedTestType.GetByTitle: apiUrl = apiName + "/title/" + inputTemplate.Title; expectedResult = new Movie[] { inputTemplate }; actualResult = await client.InvokeApiAsync <AllMovies>(apiUrl, HttpMethod.Get, null); break; case TypedTestType.GetByDate: var releaseDate = inputTemplate.ReleaseDate; apiUrl = apiName + "/date/" + releaseDate.Year + "/" + releaseDate.Month + "/" + releaseDate.Day; expectedResult = QueryTestData.TestMovies().Where(m => m.ReleaseDate == releaseDate).ToArray(); actualResult = await client.InvokeApiAsync <AllMovies>(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 <Movie, 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 <Movie, AllMovies>(apiUrl, inputTemplate); } else { actualResult = await client.InvokeApiAsync <Movie, AllMovies>(apiUrl, inputTemplate, HttpMethod.Post, queryParams); } expectedResult = QueryTestData.TestMovies().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); } Log(" - Sent request to {0}", apiUrl); List <string> errors = new List <string>(); Assert.AreEquivalent(expectedResult, actualResult.Movies); } }
public Task Query_String_Last10() => CreateQueryTestStringId( "Get last ($skip) - 10", null, null, QueryTestData.TestMovies().Length - 10);