1+ using System . Collections . Generic ;
2+ using System . Threading . Tasks ;
3+ using Xunit ;
4+ using Octokit ;
5+ using Storage . Analysis ;
6+
7+ namespace Platform . Bot . Tests
8+ {
9+ public class BugReproductionAnalyzerTests
10+ {
11+ private readonly BugReproductionAnalyzer _analyzer ;
12+
13+ public BugReproductionAnalyzerTests ( )
14+ {
15+ _analyzer = new BugReproductionAnalyzer ( ) ;
16+ }
17+
18+ [ Fact ]
19+ public async Task AnalyzeBugReproduction_WithMainFile_IdentifiesAsEntryPoint ( )
20+ {
21+ // Arrange
22+ var files = new List < RepositoryFile >
23+ {
24+ new RepositoryFile
25+ {
26+ Path = "Program.cs" ,
27+ Content = "using System;\n \n class Program\n {\n static void Main(string[] args)\n {\n Console.WriteLine(\" Hello World!\" );\n }\n }" ,
28+ IsEntryPoint = true
29+ }
30+ } ;
31+
32+ var issue = CreateMockIssue ( "Test bug" , "This is a test bug description" ) ;
33+
34+ // Act
35+ var result = await _analyzer . AnalyzeBugReproduction ( files , issue ) ;
36+
37+ // Assert
38+ Assert . Contains ( "Program.cs" , result . EntryPoints ) ;
39+ Assert . Contains ( "Program.cs" , result . CriticalFiles ) ;
40+ }
41+
42+ [ Fact ]
43+ public async Task AnalyzeBugReproduction_WithTestFile_IdentifiesAsTestFile ( )
44+ {
45+ // Arrange
46+ var files = new List < RepositoryFile >
47+ {
48+ new RepositoryFile
49+ {
50+ Path = "Tests/BugTest.cs" ,
51+ Content = "[Test]\n public void TestBug()\n {\n // Test code\n }" ,
52+ IsTestFile = true
53+ }
54+ } ;
55+
56+ var issue = CreateMockIssue ( "Test bug" , "This is a test bug description" ) ;
57+
58+ // Act
59+ var result = await _analyzer . AnalyzeBugReproduction ( files , issue ) ;
60+
61+ // Assert
62+ Assert . Contains ( "Tests/BugTest.cs" , result . TestFiles ) ;
63+ Assert . Contains ( "Tests/BugTest.cs" , result . CriticalFiles ) ;
64+ }
65+
66+ [ Fact ]
67+ public async Task AnalyzeBugReproduction_WithFileReferencedInBugReport_IdentifiesAsCritical ( )
68+ {
69+ // Arrange
70+ var files = new List < RepositoryFile >
71+ {
72+ new RepositoryFile
73+ {
74+ Path = "BuggyClass.cs" ,
75+ Content = "public class BuggyClass\n {\n public void ProblematicMethod()\n {\n throw new Exception(\" Bug!\" );\n }\n }"
76+ }
77+ } ;
78+
79+ var issue = CreateMockIssue ( "Bug in BuggyClass" , "The BuggyClass.cs file contains a problematic method that throws an exception" ) ;
80+
81+ // Act
82+ var result = await _analyzer . AnalyzeBugReproduction ( files , issue ) ;
83+
84+ // Assert
85+ Assert . Contains ( "BuggyClass.cs" , result . CriticalFiles ) ;
86+ Assert . Contains ( "BuggyClass.cs" , result . FileReasons . Keys ) ;
87+ }
88+
89+ [ Fact ]
90+ public async Task SimplifyCodebase_RemovesNonCriticalFiles ( )
91+ {
92+ // Arrange
93+ var originalFiles = new List < RepositoryFile >
94+ {
95+ new RepositoryFile { Path = "Program.cs" , Content = "static void Main() {}" , IsEntryPoint = true } ,
96+ new RepositoryFile { Path = "README.md" , Content = "# Documentation" } ,
97+ new RepositoryFile { Path = "Examples/Sample.cs" , Content = "// Example code" }
98+ } ;
99+
100+ var analysisResult = new BugAnalysisResult ( ) ;
101+ analysisResult . CriticalFiles . Add ( "Program.cs" ) ;
102+ analysisResult . RemovedFiles . Add ( "README.md" ) ;
103+ analysisResult . RemovedFiles . Add ( "Examples/Sample.cs" ) ;
104+
105+ // Act
106+ var simplifiedFiles = await _analyzer . SimplifyCodebase ( originalFiles , analysisResult ) ;
107+
108+ // Assert
109+ Assert . Single ( simplifiedFiles ) ;
110+ Assert . Contains ( simplifiedFiles , f => f . Path == "Program.cs" ) ;
111+ Assert . DoesNotContain ( simplifiedFiles , f => f . Path == "README.md" ) ;
112+ Assert . DoesNotContain ( simplifiedFiles , f => f . Path == "Examples/Sample.cs" ) ;
113+ }
114+
115+ [ Fact ]
116+ public async Task AnalyzeBugReproduction_WithMultipleFiles_CalculatesConfidenceScore ( )
117+ {
118+ // Arrange
119+ var files = new List < RepositoryFile >
120+ {
121+ new RepositoryFile
122+ {
123+ Path = "Program.cs" ,
124+ Content = "static void Main() {}" ,
125+ IsEntryPoint = true
126+ } ,
127+ new RepositoryFile
128+ {
129+ Path = "Tests/UnitTest.cs" ,
130+ Content = "[Test] public void TestMethod() {}" ,
131+ IsTestFile = true
132+ } ,
133+ new RepositoryFile
134+ {
135+ Path = "README.md" ,
136+ Content = "# Documentation"
137+ }
138+ } ;
139+
140+ var issue = CreateMockIssue ( "Test issue" , "Test description" ) ;
141+
142+ // Act
143+ var result = await _analyzer . AnalyzeBugReproduction ( files , issue ) ;
144+
145+ // Assert
146+ Assert . True ( result . ConfidenceScore >= 0.0 && result . ConfidenceScore <= 1.0 ) ;
147+ Assert . True ( result . ConfidenceScore > 0.8 ) ; // Should be high confidence with entry point and test file
148+ }
149+
150+ private Issue CreateMockIssue ( string title , string body )
151+ {
152+ // Create a mock issue for testing
153+ // Note: In a real implementation, you'd want to use a proper mocking framework
154+ // For this simple test, we'll create a minimal implementation
155+ return new Issue (
156+ url : "https://github.com/test/repo/issues/1" ,
157+ htmlUrl : "https://github.com/test/repo/issues/1" ,
158+ commentsUrl : "https://github.com/test/repo/issues/1/comments" ,
159+ eventsUrl : "https://github.com/test/repo/issues/1/events" ,
160+ number : 1 ,
161+ state : ItemState . Open ,
162+ title : title ,
163+ body : body ,
164+ user : null ,
165+ labels : new List < Label > ( ) . AsReadOnly ( ) ,
166+ assignee : null ,
167+ assignees : new List < User > ( ) . AsReadOnly ( ) ,
168+ milestone : null ,
169+ comments : 0 ,
170+ pullRequest : null ,
171+ closedAt : null ,
172+ createdAt : System . DateTimeOffset . Now ,
173+ updatedAt : System . DateTimeOffset . Now ,
174+ closedBy : null ,
175+ id : 1 ,
176+ nodeId : "node1" ,
177+ locked : false ,
178+ repository : CreateMockRepository ( ) ,
179+ reactions : null ,
180+ activeLockReason : null ,
181+ stateReason : null
182+ ) ;
183+ }
184+
185+ private Repository CreateMockRepository ( )
186+ {
187+ return new Repository (
188+ url : "https://github.com/test/repo" ,
189+ htmlUrl : "https://github.com/test/repo" ,
190+ cloneUrl : "https://github.com/test/repo.git" ,
191+ gitUrl : "git://github.com/test/repo.git" ,
192+ sshUrl : "[email protected] :test/repo.git" , 193+ svnUrl : "https://github.com/test/repo" ,
194+ mirrorUrl : null ,
195+ id : 1 ,
196+ nodeId : "node1" ,
197+ name : "repo" ,
198+ fullName : "test/repo" ,
199+ description : "Test repository" ,
200+ homepage : "" ,
201+ language : "C#" ,
202+ isPrivate : false ,
203+ fork : false ,
204+ forksCount : 0 ,
205+ stargazersCount : 0 ,
206+ watchersCount : 0 ,
207+ size : 100 ,
208+ defaultBranch : "main" ,
209+ openIssuesCount : 1 ,
210+ topics : new List < string > ( ) . AsReadOnly ( ) ,
211+ hasIssues : true ,
212+ hasProjects : true ,
213+ hasWiki : true ,
214+ hasPages : false ,
215+ hasDownloads : true ,
216+ archived : false ,
217+ disabled : false ,
218+ pushedAt : System . DateTimeOffset . Now ,
219+ createdAt : System . DateTimeOffset . Now ,
220+ updatedAt : System . DateTimeOffset . Now ,
221+ permissions : null ,
222+ owner : CreateMockUser ( ) ,
223+ parent : null ,
224+ source : null ,
225+ templatesUrl : null ,
226+ subscribersCount : 1 ,
227+ networkCount : 1 ,
228+ license : null ,
229+ forksUrl : null ,
230+ keysUrl : null ,
231+ collaboratorsUrl : null ,
232+ teamsUrl : null ,
233+ hooksUrl : null ,
234+ issueEventsUrl : null ,
235+ eventsUrl : null ,
236+ assigneesUrl : null ,
237+ branchesUrl : null ,
238+ tagsUrl : null ,
239+ blobsUrl : null ,
240+ gitTagsUrl : null ,
241+ gitRefsUrl : null ,
242+ treesUrl : null ,
243+ statusesUrl : null ,
244+ languagesUrl : null ,
245+ stargazersUrl : null ,
246+ contributorsUrl : null ,
247+ subscribersUrl : null ,
248+ commitsUrl : null ,
249+ gitCommitsUrl : null ,
250+ commentsUrl : null ,
251+ issueCommentUrl : null ,
252+ contentsUrl : null ,
253+ compareUrl : null ,
254+ mergesUrl : null ,
255+ archiveUrl : null ,
256+ downloadsUrl : null ,
257+ issuesUrl : null ,
258+ pullsUrl : null ,
259+ milestonesUrl : null ,
260+ notificationsUrl : null ,
261+ labelsUrl : null ,
262+ releasesUrl : null ,
263+ deploymentsUrl : null ,
264+ allowRebaseMerge : true ,
265+ allowSquashMerge : true ,
266+ allowMergeCommit : true ,
267+ deleteBranchOnMerge : false ,
268+ allowAutoMerge : false ,
269+ allowUpdateBranch : false ,
270+ useSquashPrTitleAsDefault : false ,
271+ squashMergeCommitTitle : null ,
272+ squashMergeCommitMessage : null ,
273+ mergeCommitTitle : null ,
274+ mergeCommitMessage : null ,
275+ visibility : RepositoryVisibility . Public ,
276+ webCommitSignoffRequired : false ,
277+ securityAndAnalysis : null ,
278+ customProperties : null
279+ ) ;
280+ }
281+
282+ private User CreateMockUser ( )
283+ {
284+ return new User (
285+ avatarUrl : "https://github.com/images/error/octocat_happy.gif" ,
286+ bio : "" ,
287+ blog : "" ,
288+ collaborators : 0 ,
289+ company : "" ,
290+ createdAt : System . DateTimeOffset . Now ,
291+ diskUsage : 0 ,
292+ 293+ followers : 0 ,
294+ following : 0 ,
295+ hireable : false ,
296+ htmlUrl : "https://github.com/test" ,
297+ totalPrivateRepos : 0 ,
298+ id : 1 ,
299+ nodeId : "node1" ,
300+ location : "" ,
301+ login : "test" ,
302+ name : "Test User" ,
303+ ownedPrivateRepos : 0 ,
304+ plan : null ,
305+ privateGists : 0 ,
306+ publicGists : 0 ,
307+ publicRepos : 1 ,
308+ updatedAt : System . DateTimeOffset . Now ,
309+ url : "https://api.github.com/users/test" ,
310+ permissions : null ,
311+ siteAdmin : false ,
312+ ldapDistinguishedName : null ,
313+ suspendedAt : null ,
314+ type : AccountType . User ,
315+ facebookId : null ,
316+ gravatar : null ,
317+ twitterUsername : null
318+ ) ;
319+ }
320+ }
321+ }
0 commit comments