private static async Task <string> GetRandomRepoFile(HttpClient client, Random rnd, CodeRepo repo, string subdirectory = "") { string jsonFilesInRepo = await client.GetStringAsync("https://api.github.com/repos/" + repo.RepoPath + subdirectory); List <dynamic> filesInRepo = JsonConvert.DeserializeObject <List <dynamic> >(jsonFilesInRepo) .Where(repoItem => (repo.UseFolders || repoItem.type == "file") && (repoItem.type == "dir" || ((string)repoItem.name).EndsWith(repo.Language.FileExtension))).ToList(); dynamic randomRepoItem = filesInRepo[rnd.Next(filesInRepo.Count)]; if (randomRepoItem.type == "dir") { return(await GetRandomRepoFile(client, rnd, repo, subdirectory + "/" + (string)randomRepoItem.name)); } string repoFilePath = randomRepoItem._links.self; string jsonFileContents = await client.GetStringAsync(repoFilePath); dynamic fileContents = JsonConvert.DeserializeObject(jsonFileContents); if (fileContents is null) { throw new JsonException("Deserialization returned null object"); } string fileString = (string)fileContents.content; // Remove non-unicode characters - for whatever reason some of the C# files had zero-width spaces in them return(Encoding.ASCII.GetString( Encoding.Convert( Encoding.UTF8, Encoding.GetEncoding( Encoding.ASCII.EncodingName, new EncoderReplacementFallback(string.Empty), new DecoderExceptionFallback()), Encoding.UTF8.GetBytes(Base64Decode(fileString))))); }
/// <summary> /// Get code source to be used in the test. /// </summary> /// <param name="client">An instance of HttpClient to use to make API calls.</param> /// <param name="jsRuntime">An IJSRuntime to use for JavaScript interop.</param> /// <param name="repo">A CodeRepo to get code from.</param> /// <param name="lines">The number of lines of code to get.</param> /// <param name="fromStart">Whether to get the code from the start of the file or to get it from a random location.</param> /// <param name="includeComments">Whether or not to include single-line comments in the code source.</param> /// <returns>A list of strings, where each item is a line in the source.</returns> public static async Task <List <string> > GetCodeSource(HttpClient client, IJSRuntime jsRuntime, CodeRepo repo, int lines, bool fromStart, bool includeComments) { Random rnd = new Random(); string fileContents = await GetRandomRepoFile(client, rnd, repo); List <string> initialLines = repo.Language == CodeLanguage.Python ? await ProcessLinesPython(jsRuntime, fileContents, includeComments) : await ProcessLinesC(jsRuntime, fileContents, includeComments, repo.Language.Enum); if (initialLines.Count > lines) { if (fromStart) { return(initialLines.Take(lines).ToList()); } int start = rnd.Next(0, initialLines.Count - lines); return(initialLines.GetRange(start, lines)); } // We need more lines return(initialLines.Concat(await GetCodeSource(client, jsRuntime, repo, lines - initialLines.Count, fromStart, includeComments)).ToList()); }