1# Copyright (C) 2020 ycmd contributors
2#
3# This file is part of ycmd.
4#
5# ycmd is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# ycmd is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with ycmd.  If not, see <http://www.gnu.org/licenses/>.
17
18from hamcrest import ( assert_that, contains_exactly, contains_string, equal_to,
19                       has_entries, has_entry, has_items )
20
21from ycmd.tests.cs import ( IsolatedYcmd, PathToTestFile, SharedYcmd,
22                            WrapOmniSharpServer )
23from ycmd.tests.test_utils import ( BuildRequest,
24                                    LocationMatcher,
25                                    RangeMatcher,
26                                    WithRetry )
27from ycmd.utils import ReadFile
28
29
30@WithRetry
31@SharedYcmd
32def Diagnostics_Basic_test( app ):
33  filepath = PathToTestFile( 'testy', 'Program.cs' )
34  with WrapOmniSharpServer( app, filepath ):
35    contents = ReadFile( filepath )
36
37    event_data = BuildRequest( filepath = filepath,
38                               event_name = 'FileReadyToParse',
39                               filetype = 'cs',
40                               contents = contents )
41    app.post_json( '/event_notification', event_data )
42
43    diag_data = BuildRequest( filepath = filepath,
44                              filetype = 'cs',
45                              contents = contents,
46                              line_num = 10,
47                              column_num = 2 )
48
49    results = app.post_json( '/detailed_diagnostic', diag_data ).json
50    assert_that( results,
51                 has_entry(
52                     'message',
53                     contains_string(
54                       "Identifier expected" ) ) )
55
56
57@SharedYcmd
58def Diagnostics_ZeroBasedLineAndColumn_test( app ):
59  filepath = PathToTestFile( 'testy', 'Program.cs' )
60  with WrapOmniSharpServer( app, filepath ):
61    contents = ReadFile( filepath )
62
63    event_data = BuildRequest( filepath = filepath,
64                               event_name = 'FileReadyToParse',
65                               filetype = 'cs',
66                               contents = contents )
67
68    results = app.post_json( '/event_notification', event_data ).json
69
70    assert_that( results, has_items(
71      has_entries( {
72        'kind': equal_to( 'ERROR' ),
73        'text': contains_string( "Identifier expected" ),
74        'location': LocationMatcher( filepath, 10, 12 ),
75        'location_extent': RangeMatcher( filepath, ( 10, 12 ), ( 10, 12 ) ),
76      } )
77    ) )
78
79
80@WithRetry
81@SharedYcmd
82def Diagnostics_WithRange_test( app ):
83  filepath = PathToTestFile( 'testy', 'DiagnosticRange.cs' )
84  with WrapOmniSharpServer( app, filepath ):
85    contents = ReadFile( filepath )
86
87    event_data = BuildRequest( filepath = filepath,
88                               event_name = 'FileReadyToParse',
89                               filetype = 'cs',
90                               contents = contents )
91
92    results = app.post_json( '/event_notification', event_data ).json
93
94    assert_that( results, contains_exactly(
95      has_entries( {
96        'kind': equal_to( 'WARNING' ),
97        'text': contains_string(
98          "The variable '\u4e5d' is assigned but its value is never used" ),
99        'location': LocationMatcher( filepath, 6, 13 ),
100        'location_extent': RangeMatcher( filepath, ( 6, 13 ), ( 6, 16 ) )
101      } )
102    ) )
103
104
105@IsolatedYcmd()
106def Diagnostics_MultipleSolution_test( app ):
107  filepaths = [ PathToTestFile( 'testy', 'Program.cs' ),
108                PathToTestFile( 'testy-multiple-solutions',
109                                'solution-named-like-folder',
110                                'testy', 'Program.cs' ) ]
111  for filepath in filepaths:
112    with WrapOmniSharpServer( app, filepath ):
113      contents = ReadFile( filepath )
114      event_data = BuildRequest( filepath = filepath,
115                                 event_name = 'FileReadyToParse',
116                                 filetype = 'cs',
117                                 contents = contents )
118
119      results = app.post_json( '/event_notification', event_data ).json
120      assert_that( results, has_items(
121        has_entries( {
122          'kind': equal_to( 'ERROR' ),
123          'text': contains_string( "Identifier expected" ),
124          'location': LocationMatcher( filepath, 10, 12 ),
125          'location_extent': RangeMatcher(
126              filepath, ( 10, 12 ), ( 10, 12 ) )
127        } )
128      ) )
129
130
131@IsolatedYcmd( { 'max_diagnostics_to_display': 1 } )
132def Diagnostics_MaximumDiagnosticsNumberExceeded_test( app ):
133  filepath = PathToTestFile( 'testy', 'MaxDiagnostics.cs' )
134  with WrapOmniSharpServer( app, filepath ):
135    contents = ReadFile( filepath )
136
137    event_data = BuildRequest( filepath = filepath,
138                               event_name = 'FileReadyToParse',
139                               filetype = 'cs',
140                               contents = contents )
141
142    results = app.post_json( '/event_notification', event_data ).json
143
144    assert_that( results, contains_exactly(
145      has_entries( {
146        'kind': equal_to( 'ERROR' ),
147        'text': contains_string( "The type 'MaxDiagnostics' already contains "
148                                 "a definition for 'test'" ),
149        'location': LocationMatcher( filepath, 4, 16 ),
150        'location_extent': RangeMatcher( filepath, ( 4, 16 ), ( 4, 20 ) )
151      } ),
152      has_entries( {
153        'kind': equal_to( 'ERROR' ),
154        'text': contains_string( 'Maximum number of diagnostics exceeded.' ),
155        'location': LocationMatcher( filepath, 1, 1 ),
156        'location_extent': RangeMatcher( filepath, ( 1, 1 ), ( 1, 1 ) ),
157        'ranges': contains_exactly(
158          RangeMatcher( filepath, ( 1, 1 ), ( 1, 1 ) )
159        )
160      } )
161    ) )
162
163
164def Dummy_test():
165  # Workaround for https://github.com/pytest-dev/pytest-rerunfailures/issues/51
166  assert True
167